前端基于THREE.js的3D全景,支持鼠标控制和手机陀螺仪的切换

小程序开发前端
前端程序开发
程序开发前端后端

html 代码

<!DOCTYPE html>
    <head>
        <meta charset=”utf-8″ />
        <meta name=”renderer” content=”webkit” />
        <script>
            ‘use strict’
            ;(function(_window) {
                var navigatorUserAgent = navigator.userAgent
                var iPhone = navigatorUserAgent.indexOf(‘iPhone’)
                if (iPhone > -1) {
                    var dpr = Number(window.devicePixelRatio),
                        one_dpr = 1 / dpr
                } else {
                    var dpr = 1,
                        one_dpr = 1
                }
                var writeText =
                    ‘<meta name=”viewport” content=”width=device-width,initial-scale=’ +
                    one_dpr +
                    ‘,maximum-scale=’ +
                    one_dpr +
                    ‘,minimum-scale=’ +
                    one_dpr +
                    ‘,user-scalable=no”>\n <meta name=”\’flexible” content=”initial-dpr=’ +
                    dpr +
                    ‘”>’
                document.write(writeText)
                var html = document.getElementsByTagName(‘html’)
                var F0 = 75
                html[0].setAttribute(‘data-dpr’, dpr)
                var getFontSize = function getFontSize() {
                    var windowWidth = window.innerWidth
                    html[0].style.fontSize = (F0 * windowWidth) / 750 + ‘px’
                }
                getFontSize()
                _window.addEventListener(‘resize’, getFontSize, false)
            })(window)
        </script>
        <style>
            body {
                margin: 0;
            }
            html,
            body,
            #CanvasBody {
                width: 100%;
                height: 100%;
                overflow: hidden;
            }
            #CanvasBody {
                position: relative;
            }
            #onDevice {
                position: absolute;
                bottom: 0;
                right: 0;
                z-index: 2;
                padding: 12px 18px;
                font-size: 20px;
                border: 1px solid #ddd;
                background-color: #fff;
                cursor: pointer;
                -webkit-appearance: none;
            }
        </style>
    </head>
    <body>
        <div id=”CanvasBody”>
            <input id=”onDevice” type=”button” value=”开启陀螺仪” />
        </div>
        <script src=”https://cdn.bootcss.com/three.js/r76/three.min.js”></script>
        <script src=”https://cdn.bootcss.com/stats.js/r16/Stats.min.js”></script>
        <!– 鼠标控制 (OrbitControls.js) –>
        <script>
            THREE.OrbitControls = function(object, domElement) {
                this.object = object
                this.domElement =
                    domElement !== undefined ? domElement : document
                this.enabled = true
                this.target = new THREE.Vector3()
                this.minDistance = 0
                this.maxDistance = Infinity
                this.minZoom = 0
                this.maxZoom = Infinity
                this.minPolarAngle = 0
                this.maxPolarAngle = Math.PI
                this.minAzimuthAngle = -Infinity
                this.maxAzimuthAngle = Infinity
                this.enableDamping = false
                this.dampingFactor = 0.25
                this.enableZoom = true
                this.zoomSpeed = 1.0
                this.enableRotate = true
                this.rotateSpeed = 1.0
                this.enablePan = true
                this.keyPanSpeed = 7.0
                this.autoRotate = false
                this.autoRotateSpeed = 2.0
                this.enableKeys = true
                this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 }
                this.mouseButtons = {
                    ORBIT: THREE.MOUSE.LEFT,
                    ZOOM: THREE.MOUSE.MIDDLE,
                    PAN: THREE.MOUSE.RIGHT,
                }
                this.target0 = this.target.clone()
                this.position0 = this.object.position.clone()
                this.zoom0 = this.object.zoom
                this.getPolarAngle = function() {
                    return phi
                }
                this.getAzimuthalAngle = function() {
                    return theta
                }
                this.reset = function() {
                    scope.target.copy(scope.target0)
                    scope.object.position.copy(scope.position0)
                    scope.object.zoom = scope.zoom0
                    scope.object.updateProjectionMatrix()
                    scope.dispatchEvent(changeEvent)
                    scope.update()
                    state = STATE.NONE
                }
                this.update = (function() {
                    var offset = new THREE.Vector3()
                    var quat = new THREE.Quaternion().setFromUnitVectors(
                        object.up,
                        new THREE.Vector3(0, 1, 0),
                    )
                    var quatInverse = quat.clone().inverse()
                    var lastPosition = new THREE.Vector3()
                    var lastQuaternion = new THREE.Quaternion()
                    return function() {
                        var position = scope.object.position
                        offset.copy(position).sub(scope.target)
                        offset.applyQuaternion(quat)
                        spherical.setFromVector3(offset)
                        if (scope.autoRotate && state === STATE.NONE) {
                            rotateLeft(getAutoRotationAngle())
                        }
                        spherical.theta += sphericalDelta.theta
                        spherical.phi += sphericalDelta.phi
                        spherical.theta = Math.max(
                            scope.minAzimuthAngle,
                            Math.min(scope.maxAzimuthAngle, spherical.theta),
                        )
                        spherical.phi = Math.max(
                            scope.minPolarAngle,
                            Math.min(scope.maxPolarAngle, spherical.phi),
                        )
                        spherical.makeSafe()
                        spherical.radius *= scale
                        spherical.radius = Math.max(
                            scope.minDistance,
                            Math.min(scope.maxDistance, spherical.radius),
                        )
                        scope.target.add(panOffset)
                        offset.setFromSpherical(spherical)
                        offset.applyQuaternion(quatInverse)
                        position.copy(scope.target).add(offset)
                        scope.object.lookAt(scope.target)
                        if (scope.enableDamping === true) {
                            sphericalDelta.theta *= 1 – scope.dampingFactor
                            sphericalDelta.phi *= 1 – scope.dampingFactor
                        } else {
                            sphericalDelta.set(0, 0, 0)
                        }
                        scale = 1
                        panOffset.set(0, 0, 0)
                        if (
                            zoomChanged ||
                            lastPosition.distanceToSquared(
                                scope.object.position,
                            ) > EPS ||
                            8 *
                                (1 –
                                    lastQuaternion.dot(
                                        scope.object.quaternion,
                                    )) >
                                EPS
                        ) {
                            scope.dispatchEvent(changeEvent)
                            lastPosition.copy(scope.object.position)
                            lastQuaternion.copy(scope.object.quaternion)
                            zoomChanged = false
                            return true
                        }
                        return false
                    }
                })()
                this.dispose = function() {
                    scope.domElement.removeEventListener(
                        ‘contextmenu’,
                        onContextMenu,
                        false,
                    )
                    scope.domElement.removeEventListener(
                        ‘mousedown’,
                        onMouseDown,
                        false,
                    )
                    scope.domElement.removeEventListener(
                        ‘mousewheel’,
                        onMouseWheel,
                        false,
                    )
                    scope.domElement.removeEventListener(
                        ‘MozMousePixelScroll’,
                        onMouseWheel,
                        false,
                    )
                    scope.domElement.removeEventListener(
                        ‘touchstart’,
                        onTouchStart,
                        false,
                    )
                    scope.domElement.removeEventListener(
                        ‘touchend’,
                        onTouchEnd,
                        false,
                    )
                    scope.domElement.removeEventListener(
                        ‘touchmove’,
                        onTouchMove,
                        false,
                    )
                    document.removeEventListener(
                        ‘mousemove’,
                        onMouseMove,
                        false,
                    )
                    document.removeEventListener(‘mouseup’, onMouseUp, false)
                    document.removeEventListener(‘mouseout’, onMouseUp, false)
                    window.removeEventListener(‘keydown’, onKeyDown, false)
                }
                var scope = this
                var changeEvent = { type: ‘change’ }
                var startEvent = { type: ‘start’ }
                var endEvent = { type: ‘end’ }
                var STATE = {
                    NONE: -1,
                    ROTATE: 0,
                    DOLLY: 1,
                    PAN: 2,
                    TOUCH_ROTATE: 3,
                    TOUCH_DOLLY: 4,
                    TOUCH_PAN: 5,
                }
                var state = STATE.NONE
                var EPS = 0.000001
                var spherical = new THREE.Spherical()
                var sphericalDelta = new THREE.Spherical()
                var scale = 1
                var panOffset = new THREE.Vector3()
                var zoomChanged = false
                var rotateStart = new THREE.Vector2()
                var rotateEnd = new THREE.Vector2()
                var rotateDelta = new THREE.Vector2()
                var panStart = new THREE.Vector2()
                var panEnd = new THREE.Vector2()
                var panDelta = new THREE.Vector2()
                var dollyStart = new THREE.Vector2()
                var dollyEnd = new THREE.Vector2()
                var dollyDelta = new THREE.Vector2()
                function getAutoRotationAngle() {
                    return ((2 * Math.PI) / 60 / 60) * scope.autoRotateSpeed
                }
                function getZoomScale() {
                    return Math.pow(0.95, scope.zoomSpeed)
                }
                function rotateLeft(angle) {
                    sphericalDelta.theta -= angle
                }
                function rotateUp(angle) {
                    sphericalDelta.phi -= angle
                }
                var panLeft = (function() {
                    var v = new THREE.Vector3()
                    return function panLeft(distance, objectMatrix) {
                        v.setFromMatrixColumn(objectMatrix, 0)
                        v.multiplyScalar(-distance)
                        panOffset.add(v)
                    }
                })()
                var panUp = (function() {
                    var v = new THREE.Vector3()
                    return function panUp(distance, objectMatrix) {
                        v.setFromMatrixColumn(objectMatrix, 1)
                        v.multiplyScalar(distance)
                        panOffset.add(v)
                    }
                })()
                var pan = (function() {
                    var offset = new THREE.Vector3()
                    return function(deltaX, deltaY) {
                        var element =
                            scope.domElement === document
                                ? scope.domElement.body
                                : scope.domElement
                        if (scope.object instanceof THREE.PerspectiveCamera) {
                            var position = scope.object.position
                            offset.copy(position).sub(scope.target)
                            var targetDistance = offset.length()
                            targetDistance *= Math.tan(
                                ((scope.object.fov / 2) * Math.PI) / 180.0,
                            )
                            panLeft(
                                (2 * deltaX * targetDistance) /
                                    element.clientHeight,
                                scope.object.matrix,
                            )
                            panUp(
                                (2 * deltaY * targetDistance) /
                                    element.clientHeight,
                                scope.object.matrix,
                            )
                        } else if (
                            scope.object instanceof THREE.OrthographicCamera
                        ) {
                            panLeft(
                                (deltaX *
                                    (scope.object.right – scope.object.left)) /
                                    scope.object.zoom /
                                    element.clientWidth,
                                scope.object.matrix,
                            )
                            panUp(
                                (deltaY *
                                    (scope.object.top – scope.object.bottom)) /
                                    scope.object.zoom /
                                    element.clientHeight,
                                scope.object.matrix,
                            )
                        } else {
                            console.warn(
                                ‘WARNING: OrbitControls.js encountered an unknown camera type – pan disabled.’,
                            )
                            scope.enablePan = false
                        }
                    }
                })()
                function dollyIn(dollyScale) {
                    if (scope.object instanceof THREE.PerspectiveCamera) {
                        scale /= dollyScale
                    } else if (
                        scope.object instanceof THREE.OrthographicCamera
                    ) {
                        scope.object.zoom = Math.max(
                            scope.minZoom,
                            Math.min(
                                scope.maxZoom,
                                scope.object.zoom * dollyScale,
                            ),
                        )
                        scope.object.updateProjectionMatrix()
                        zoomChanged = true
                    } else {
                        console.warn(
                            ‘WARNING: OrbitControls.js encountered an unknown camera type – dolly/zoom disabled.’,
                        )
                        scope.enableZoom = false
                    }
                }
                function dollyOut(dollyScale) {
                    if (scope.object instanceof THREE.PerspectiveCamera) {
                        scale *= dollyScale
                    } else if (
                        scope.object instanceof THREE.OrthographicCamera
                    ) {
                        scope.object.zoom = Math.max(
                            scope.minZoom,
                            Math.min(
                                scope.maxZoom,
                                scope.object.zoom / dollyScale,
                            ),
                        )
                        scope.object.updateProjectionMatrix()
                        zoomChanged = true
                    } else {
                        console.warn(
                            ‘WARNING: OrbitControls.js encountered an unknown camera type – dolly/zoom disabled.’,
                        )
                        scope.enableZoom = false
                    }
                }
                function handleMouseDownRotate(event) {
                    rotateStart.set(event.clientX, event.clientY)
                }
                function handleMouseDownDolly(event) {
                    dollyStart.set(event.clientX, event.clientY)
                }
                function handleMouseDownPan(event) {
                    panStart.set(event.clientX, event.clientY)
                }
                function handleMouseMoveRotate(event) {
                    rotateEnd.set(event.clientX, event.clientY)
                    rotateDelta.subVectors(rotateEnd, rotateStart)
                    var element =
                        scope.domElement === document
                            ? scope.domElement.body
                            : scope.domElement
                    rotateLeft(
                        ((2 * Math.PI * rotateDelta.x) / element.clientWidth) *
                            scope.rotateSpeed,
                    )
                    rotateUp(
                        ((2 * Math.PI * rotateDelta.y) / element.clientHeight) *
                            scope.rotateSpeed,
                    )
                    rotateStart.copy(rotateEnd)
                    scope.update()
                }
                function handleMouseMoveDolly(event) {
                    dollyEnd.set(event.clientX, event.clientY)
                    dollyDelta.subVectors(dollyEnd, dollyStart)
                    if (dollyDelta.y > 0) {
                        dollyIn(getZoomScale())
                    } else if (dollyDelta.y < 0) {
                        dollyOut(getZoomScale())
                    }
                    dollyStart.copy(dollyEnd)
                    scope.update()
                }
                function handleMouseMovePan(event) {
                    panEnd.set(event.clientX, event.clientY)
                    panDelta.subVectors(panEnd, panStart)
                    pan(panDelta.x, panDelta.y)
                    panStart.copy(panEnd)
                    scope.update()
                }
                function handleMouseUp(event) {}
                function handleMouseWheel(event) {
                    var delta = 0
                    if (event.wheelDelta !== undefined) {
                        delta = event.wheelDelta
                    } else if (event.detail !== undefined) {
                        delta = -event.detail
                    }
                    if (delta > 0) {
                        dollyOut(getZoomScale())
                    } else if (delta < 0) {
                        dollyIn(getZoomScale())
                    }
                    scope.update()
                }
                function handleKeyDown(event) {
                    switch (event.keyCode) {
                        case scope.keys.UP:
                            pan(0, scope.keyPanSpeed)
                            scope.update()
                            break
                        case scope.keys.BOTTOM:
                            pan(0, -scope.keyPanSpeed)
                            scope.update()
                            break
                        case scope.keys.LEFT:
                            pan(scope.keyPanSpeed, 0)
                            scope.update()
                            break
                        case scope.keys.RIGHT:
                            pan(-scope.keyPanSpeed, 0)
                            scope.update()
                            break
                    }
                }
                function handleTouchStartRotate(event) {
                    rotateStart.set(
                        event.touches[0].pageX,
                        event.touches[0].pageY,
                    )
                }
                function handleTouchStartDolly(event) {
                    var dx = event.touches[0].pageX – event.touches[1].pageX
                    var dy = event.touches[0].pageY – event.touches[1].pageY
                    var distance = Math.sqrt(dx * dx + dy * dy)
                    dollyStart.set(0, distance)
                }
                function handleTouchStartPan(event) {
                    panStart.set(event.touches[0].pageX, event.touches[0].pageY)
                }
                function handleTouchMoveRotate(event) {
                    rotateEnd.set(
                        event.touches[0].pageX,
                        event.touches[0].pageY,
                    )
                    rotateDelta.subVectors(rotateEnd, rotateStart)
                    var element =
                        scope.domElement === document
                            ? scope.domElement.body
                            : scope.domElement
                    rotateLeft(
                        ((2 * Math.PI * rotateDelta.x) / element.clientWidth) *
                            scope.rotateSpeed,
                    )
                    rotateUp(
                        ((2 * Math.PI * rotateDelta.y) / element.clientHeight) *
                            scope.rotateSpeed,
                    )
                    rotateStart.copy(rotateEnd)
                    scope.update()
                }
                function handleTouchMoveDolly(event) {
                    var dx = event.touches[0].pageX – event.touches[1].pageX
                    var dy = event.touches[0].pageY – event.touches[1].pageY
                    var distance = Math.sqrt(dx * dx + dy * dy)
                    dollyEnd.set(0, distance)
                    dollyDelta.subVectors(dollyEnd, dollyStart)
                    if (dollyDelta.y > 0) {
                        dollyOut(getZoomScale())
                    } else if (dollyDelta.y < 0) {
                        dollyIn(getZoomScale())
                    }
                    dollyStart.copy(dollyEnd)
                    scope.update()
                }
                function handleTouchMovePan(event) {
                    panEnd.set(event.touches[0].pageX, event.touches[0].pageY)
                    panDelta.subVectors(panEnd, panStart)
                    pan(panDelta.x, panDelta.y)
                    panStart.copy(panEnd)
                    scope.update()
                }
                function handleTouchEnd(event) {}
                function onMouseDown(event) {
                    if (scope.enabled === false) {
                        return
                    }
                    event.preventDefault()
                    if (event.button === scope.mouseButtons.ORBIT) {
                        if (scope.enableRotate === false) {
                            return
                        }
                        handleMouseDownRotate(event)
                        state = STATE.ROTATE
                    } else if (event.button === scope.mouseButtons.ZOOM) {
                        if (scope.enableZoom === false) {
                            return
                        }
                        handleMouseDownDolly(event)
                        state = STATE.DOLLY
                    } else if (event.button === scope.mouseButtons.PAN) {
                        if (scope.enablePan === false) {
                            return
                        }
                        handleMouseDownPan(event)
                        state = STATE.PAN
                    }
                    if (state !== STATE.NONE) {
                        document.addEventListener(
                            ‘mousemove’,
                            onMouseMove,
                            false,
                        )
                        document.addEventListener(‘mouseup’, onMouseUp, false)
                        document.addEventListener(‘mouseout’, onMouseUp, false)
                        scope.dispatchEvent(startEvent)
                    }
                }
                function onMouseMove(event) {
                    if (scope.enabled === false) {
                        return
                    }
                    event.preventDefault()
                    if (state === STATE.ROTATE) {
                        if (scope.enableRotate === false) {
                            return
                        }
                        handleMouseMoveRotate(event)
                    } else if (state === STATE.DOLLY) {
                        if (scope.enableZoom === false) {
                            return
                        }
                        handleMouseMoveDolly(event)
                    } else if (state === STATE.PAN) {
                        if (scope.enablePan === false) {
                            return
                        }
                        handleMouseMovePan(event)
                    }
                }
                function onMouseUp(event) {
                    if (scope.enabled === false) {
                        return
                    }
                    handleMouseUp(event)
                    document.removeEventListener(
                        ‘mousemove’,
                        onMouseMove,
                        false,
                    )
                    document.removeEventListener(‘mouseup’, onMouseUp, false)
                    document.removeEventListener(‘mouseout’, onMouseUp, false)
                    scope.dispatchEvent(endEvent)
                    state = STATE.NONE
                }
                function onMouseWheel(event) {
                    if (
                        scope.enabled === false ||
                        scope.enableZoom === false ||
                        (state !== STATE.NONE && state !== STATE.ROTATE)
                    ) {
                        return
                    }
                    event.preventDefault()
                    event.stopPropagation()
                    handleMouseWheel(event)
                    scope.dispatchEvent(startEvent)
                    scope.dispatchEvent(endEvent)
                }
                function onKeyDown(event) {
                    if (
                        scope.enabled === false ||
                        scope.enableKeys === false ||
                        scope.enablePan === false
                    ) {
                        return
                    }
                    handleKeyDown(event)
                }
                function onTouchStart(event) {
                    if (scope.enabled === false) {
                        return
                    }
                    switch (event.touches.length) {
                        case 1:
                            if (scope.enableRotate === false) {
                                return
                            }
                            handleTouchStartRotate(event)
                            state = STATE.TOUCH_ROTATE
                            break
                        case 2:
                            if (scope.enableZoom === false) {
                                return
                            }
                            handleTouchStartDolly(event)
                            state = STATE.TOUCH_DOLLY
                            break
                        case 3:
                            if (scope.enablePan === false) {
                                return
                            }
                            handleTouchStartPan(event)
                            state = STATE.TOUCH_PAN
                            break
                        default:
                            state = STATE.NONE
                    }
                    if (state !== STATE.NONE) {
                        scope.dispatchEvent(startEvent)
                    }
                }
                function onTouchMove(event) {
                    if (scope.enabled === false) {
                        return
                    }
                    event.preventDefault()
                    event.stopPropagation()
                    switch (event.touches.length) {
                        case 1:
                            if (scope.enableRotate === false) {
                                return
                            }
                            if (state !== STATE.TOUCH_ROTATE) {
                                return
                            }
                            handleTouchMoveRotate(event)
                            break
                        case 2:
                            if (scope.enableZoom === false) {
                                return
                            }
                            if (state !== STATE.TOUCH_DOLLY) {
                                return
                            }
                            handleTouchMoveDolly(event)
                            break
                        case 3:
                            if (scope.enablePan === false) {
                                return
                            }
                            if (state !== STATE.TOUCH_PAN) {
                                return
                            }
                            handleTouchMovePan(event)
                            break
                        default:
                            state = STATE.NONE
                    }
                }
                function onTouchEnd(event) {
                    if (scope.enabled === false) {
                        return
                    }
                    handleTouchEnd(event)
                    scope.dispatchEvent(endEvent)
                    state = STATE.NONE
                }
                function onContextMenu(event) {
                    event.preventDefault()
                }
                scope.domElement.addEventListener(
                    ‘contextmenu’,
                    onContextMenu,
                    false,
                )
                scope.domElement.addEventListener(
                    ‘mousedown’,
                    onMouseDown,
                    false,
                )
                scope.domElement.addEventListener(
                    ‘mousewheel’,
                    onMouseWheel,
                    false,
                )
                scope.domElement.addEventListener(
                    ‘MozMousePixelScroll’,
                    onMouseWheel,
                    false,
                )
                scope.domElement.addEventListener(
                    ‘touchstart’,
                    onTouchStart,
                    false,
                )
                scope.domElement.addEventListener(‘touchend’, onTouchEnd, false)
                scope.domElement.addEventListener(
                    ‘touchmove’,
                    onTouchMove,
                    false,
                )
                window.addEventListener(‘keydown’, onKeyDown, false)
                this.update()
            }
            THREE.OrbitControls.prototype = Object.create(
                THREE.EventDispatcher.prototype,
            )
            THREE.OrbitControls.prototype.constructor = THREE.OrbitControls
            Object.defineProperties(THREE.OrbitControls.prototype, {
                center: {
                    get: function() {
                        console.warn(
                            ‘THREE.OrbitControls: .center has been renamed to .target’,
                        )
                        return this.target
                    },
                },
                noZoom: {
                    get: function() {
                        console.warn(
                            ‘THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.’,
                        )
                        return !this.enableZoom
                    },
                    set: function(value) {
                        console.warn(
                            ‘THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.’,
                        )
                        this.enableZoom = !value
                    },
                },
                noRotate: {
                    get: function() {
                        console.warn(
                            ‘THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.’,
                        )
                        return !this.enableRotate
                    },
                    set: function(value) {
                        console.warn(
                            ‘THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.’,
                        )
                        this.enableRotate = !value
                    },
                },
                noPan: {
                    get: function() {
                        console.warn(
                            ‘THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.’,
                        )
                        return !this.enablePan
                    },
                    set: function(value) {
                        console.warn(
                            ‘THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.’,
                        )
                        this.enablePan = !value
                    },
                },
                noKeys: {
                    get: function() {
                        console.warn(
                            ‘THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.’,
                        )
                        return !this.enableKeys
                    },
                    set: function(value) {
                        console.warn(
                            ‘THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.’,
                        )
                        this.enableKeys = !value
                    },
                },
                staticMoving: {
                    get: function() {
                        console.warn(
                            ‘THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.’,
                        )
                        return !this.constraint.enableDamping
                    },
                    set: function(value) {
                        console.warn(
                            ‘THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.’,
                        )
                        this.constraint.enableDamping = !value
                    },
                },
                dynamicDampingFactor: {
                    get: function() {
                        console.warn(
                            ‘THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.’,
                        )
                        return this.constraint.dampingFactor
                    },
                    set: function(value) {
                        console.warn(
                            ‘THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.’,
                        )
                        this.constraint.dampingFactor = value
                    },
                },
            })
        </script>
        <!– 控制陀螺仪 (DeviceOrientationControls.js) –>
        <script>
            THREE.DeviceOrientationControls = function(object) {
                var scope = this
                this.object = object
                this.object.rotation.reorder(‘YXZ’)
                this.enabled = true
                this.deviceOrientation = {}
                this.screenOrientation = 0
                this.alpha = 0
                this.alphaOffsetAngle = 0
                var onDeviceOrientationChangeEvent = function(event) {
                    scope.deviceOrientation = event
                }
                var onScreenOrientationChangeEvent = function() {
                    scope.screenOrientation = window.orientation || 0
                }
                var setObjectQuaternion = (function() {
                    var zee = new THREE.Vector3(0, 0, 1)
                    var euler = new THREE.Euler()
                    var q0 = new THREE.Quaternion()
                    var q1 = new THREE.Quaternion(
                        -Math.sqrt(0.5),
                        0,
                        0,
                        Math.sqrt(0.5),
                    )
                    return function(quaternion, alpha, beta, gamma, orient) {
                        euler.set(beta, alpha, -gamma, ‘YXZ’)
                        quaternion.setFromEuler(euler)
                        quaternion.multiply(q1)
                        quaternion.multiply(q0.setFromAxisAngle(zee, -orient))
                    }
                })()
                this.connect = function() {
                    onScreenOrientationChangeEvent()
                    window.addEventListener(
                        ‘orientationchange’,
                        onScreenOrientationChangeEvent,
                        false,
                    )
                    window.addEventListener(
                        ‘deviceorientation’,
                        onDeviceOrientationChangeEvent,
                        false,
                    )
                    scope.enabled = true
                }
                this.disconnect = function() {
                    window.removeEventListener(
                        ‘orientationchange’,
                        onScreenOrientationChangeEvent,
                        false,
                    )
                    window.removeEventListener(
                        ‘deviceorientation’,
                        onDeviceOrientationChangeEvent,
                        false,
                    )
                    scope.enabled = false
                }
                this.update = function() {
                    if (scope.enabled === false) {
                        return
                    }
                    var alpha = scope.deviceOrientation.alpha
                        ? THREE.Math.degToRad(scope.deviceOrientation.alpha) +
                         this.alphaOffsetAngle
                        : 0
                    var beta = scope.deviceOrientation.beta
                        ? THREE.Math.degToRad(scope.deviceOrientation.beta)
                        : 0
                    var gamma = scope.deviceOrientation.gamma
                        ? THREE.Math.degToRad(scope.deviceOrientation.gamma)
                        : 0
                    var orient = scope.screenOrientation
                        ? THREE.Math.degToRad(scope.screenOrientation)
                        : 0
                    setObjectQuaternion(
                        scope.object.quaternion,
                        alpha,
                        beta,
                        gamma,
                        orient,
                    )
                    this.alpha = alpha
                }
                this.updateAlphaOffsetAngle = function(angle) {
                    this.alphaOffsetAngle = angle
                    this.update()
                }
                this.dispose = function() {
                    this.disconnect()
                }
                this.connect()
            }
        </script>
        <!– 代码 –>
        <script>
            “use strict”;
                    (function (CanvasBody, _window) {
                        var Scene = void 0,
                        Camera = void 0,
                        Renderer = void 0,
                        FpsStats = void 0,
                        AnimateFrame = void 0,
                        Controls = void 0,
                        Devices = void 0; // 场景,照相机,渲染器,FPS监视器,渲染定时器,控制器,陀螺仪
                        var onDevice = document.getElementById(“onDevice”);
                        var isDeviceing = 0; // 陀螺仪状态
             /* 初始化函数 */
                        // 初始化场景
                        function initScene() {
                            Scene = new THREE.Scene();
                        }
                        // 初始化照相机
                        function initCamera() {
                            Camera = new THREE.PerspectiveCamera(60, CanvasBody.clientWidth / CanvasBody.clientHeight, 1, 3000);
                            Camera.position.set(1, 0, 0);
                            Camera.lookAt({ x: 200, y: 0, z: 0 });
                        }
                        // 初始化渲染器
                        function initRenderer() {
                            Renderer = new THREE.WebGLRenderer();
                            Renderer.setSize(CanvasBody.clientWidth, CanvasBody.clientHeight);
                            Renderer.setClearColor(0x000000, 1);
                            CanvasBody.appendChild(Renderer.domElement);
                        }
                        // 初始化监视器
                        function initFpsStats() {
                            FpsStats = new Stats();
                            CanvasBody.appendChild(FpsStats.domElement);
                            FpsStats.domElement.style.cssText = “position: absolute;top: 0;left: 0;”;
                        }
                        // 初始化控制器
                        function initControls() {
                            Controls = new THREE.OrbitControls(Camera);
                        }
                        // 初始化陀螺仪
                        function initDevices() {
                            Devices = new THREE.DeviceOrientationControls(Camera);
                        }
             /* 窗口改变事件 */
             function windowChange() {
                            initCamera();
                            Renderer.setSize(CanvasBody.clientWidth, CanvasBody.clientHeight);
                            initDevices();
                            initControls();
                        }
             /* 控制陀螺仪 */
             function controlDevice(event) {
                            if (isDeviceing === 0) {
                                isDeviceing = 1;
                                onDevice.value = “关闭陀螺仪”;
                            } else {
                                isDeviceing = 0;
                                onDevice.value = “开启陀螺仪”;
                            }
                        }
             /* 动画 */
             function animate(time) {
                            FpsStats.begin();
                            Renderer.clear();
                            isDeviceing === 0 ? Controls.update() : Devices.update();
                            Renderer.render(Scene, Camera);
                            FpsStats.end();
                            AnimateFrame = requestAnimationFrame(animate);
                        }
             /* 初始化 */
             function init() {
                            // 初始化
                            initScene();
                            initCamera();
                            initRenderer();
                            initFpsStats();
                            initControls();
                            initDevices();
                            // 初始化绑定陀螺仪
                            Devices.connect();
                            _window.addEventListener(“resize”, windowChange, false);
                            onDevice.addEventListener(“click”, controlDevice, false);
                            AnimateFrame = requestAnimationFrame(animate);
                        }
                        init();
             /* 场景内物体 */
             (function () {
                            var r = Math.sqrt(5000 * 1827 / 4 / Math.PI);
                            var texture = THREE.ImageUtils.loadTexture(“http://cdn.attach.w3cfuns.com/notes/pics/201606/14/141100b7m85b4k8kb3337z.jpg”, {}, function () {
                                var geometry = new THREE.SphereGeometry(r, 100, 100);
                                var material = new THREE.MeshLambertMaterial({< br />
                                    map: texture,
             side: THREE.DoubleSide < br />
             });
                            var mesh = new THREE.Mesh(geometry, material);
                            Scene.add(mesh);
                            mesh.position.set(0, 0, 0);
                                 var al = new THREE.AmbientLight(0xffffff);
                                    Scene.add(al);
                                    });
                                    })();
                                    })(document.getElementById(“CanvasBody”), window);
        </script>
    </body>
</html>
前端 小程序开发
程序开发前端和后端
前端_后端程序开发知识
赞(0)
前端开发者 » 前端基于THREE.js的3D全景,支持鼠标控制和手机陀螺仪的切换
64K

评论 抢沙发

评论前必须登录!