js封装

2018-12-28  本文已影响0人  海货
/**
 * Created by LPH on 2017/11/27.
 */
$(document).ready(function() {
    var href = location.href;
    var key = "";
    if(href.indexOf("key") > 0) {
        key = href.substring(href.indexOf("key") + 4);
    }
    new SupportComponent(key, "#camera");
});

"use strict";

var SupportComponent = (function() {
    var SupportComponent = function(key, target) {
        return new SupportComponent.fn.init(key, target);
    };

    SupportComponent.fn = SupportComponent.prototype = {
        constructor: SupportComponent,
        init: function(key, target) {
            var _this = this;
            _this.scaning = false;
            _this.rendering = false;
            _this.deviceIsMobile = true;
            _this.deviceIsAndroid = true;
            _this.isWebRTC = false;
            _this.openCameraControl = true;
            _this.clipScreenAllowed = false;
            _this.interactingSupport = false;
            _this.timeCheck = true;
            _this.mediaCheck = true;
            _this.renderCount = 0;
            _this.delay = 200;
            _this.scanCount = 0;
            _this.maxScanCount = 100;
            _this.maxWidth = 240;
            _this.maxHeight = 240;
            _this.recoApi = "/v3/reco/recognizeByData";
            _this.domainApi = "/api/editor/domain";
            _this.transformVideoApi = "/api/editor/videourl";
            _this.resourceDomain = "";
            _this.key = key;
            _this.target = target;
            _this.cameras = [];
            _this.backCameras = [];
            _this.objects = [];
            _this.audio = null;
            _this.stream = null;
            _this.scene = null;
            _this.camera = null;
            _this.constraints = {
                audio: false,
                video: {
                    frameRate: {
                        max:    15
                    }
                }
            };
            if(_this.key == "") {
                _this.toggleLoadingStatus("hide", "WebAR链接不完整,请确认访问链接是否正确");
            } else {
                _this.checkDeviceIsPc();
                _this.checkBrowserMedia();
            }
        },
        checkDeviceIsPc: function() {
            var _this = this;
            var userAgentInfo = navigator.userAgent;
            var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod");
            _this.deviceIsMobile = false;
            for(var v = 0; v < Agents.length; v++) {
                if(userAgentInfo.indexOf(Agents[v]) > 0) {
                    _this.deviceIsMobile = true;
                    break;
                }
            }
        },
        checkBrowserMedia: function() {
            var _this = this;
            var ua = navigator.userAgent.toLowerCase();
            _this.deviceIsAndroid = !!(+ua.indexOf("android") + 1);

            if(ua.match(/MicroMessenger/i) == 'micromessenger' && ua.indexOf("iphone") > 0) {
                $(".fixed").hide();
                _this.selectImage();
            } else {
                if (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices) {
                    _this.selectImage();
                } else if(typeof navigator.getUserMedia === "undefined" || typeof navigator.mediaDevices === "undefined" || typeof navigator.mediaDevices.getUserMedia === "undefined") {
                    _this.selectImage();
                } else if(navigator.mediaDevices.getUserMedia !== undefined) {
                    _this.getUserMedia();
                } else {
                    _this.selectImage();
                }
            }
        },
        selectImage: function() {
            var _this = this;
            var windowURL = window.URL || window.webkitURL;
            var dataUrl = "";
            _this.isWebRTC = false;

            $("#photo, #file").remove();
            $("body").append("<button id='photo'>拍图扫描</button><input id='file' type='file' accept='image/*'/>");
            $("body > p").html("");

            $("#photo").off().on("click", function() {
                $("#file").trigger("click");
            });
            $("#file").off().change(function(e) {
                var file = $("#file")[0].files[0];
                if(file != null) {
                    if(!/image\/\w+/.test(file.type)){
                        _this.toggleLoadingStatus("hide", "请上传图片");
                        return false;
                    }
                } else {
                    return false;
                }
                var fileReader = new FileReader();

                fileReader.onload = function(e){
                    _this.render(e.target.result, 0);
                };
                fileReader.readAsDataURL(file);
            });
        },
        render: function(src, angle) {

            var _this = this;
            var HasTranslateAngle = 0;
            var image = new Image();
            image.onload = function(){
                // 获取 canvas DOM 对象
                angle += HasTranslateAngle;
                if (angle == 0 ||angle == 360) {
                    angle =0;
                    HasTranslateAngle = 0;
                }else{
                    HasTranslateAngle += 90;
                    angle = HasTranslateAngle;
                }
                var canvas = document.getElementById("imageCvs");
                _this.resizeImage(image, _this.maxWidth, _this.maxHeight);
                canvas.width = image.width;
                canvas.height = image.height;
                var ctx = canvas.getContext("2d");
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                var x = 0;
                var y = 0;
                if(angle > 0) {
                    if(angle == 90) {
                        x = canvas.height;
                        y = 0;
                        canvas.width = image.height;
                        canvas.height = image.width;
                    }else if (angle == 180) {
                        x = canvas.width;
                        y = canvas.height;
                        canvas.width = image.width;
                        canvas.height = image.height;
                    }else{
                        x = 0;
                        y = canvas.width;
                        canvas.width = image.height;
                        canvas.height = image.width;
                    }
                    ctx.save();
                    ctx.translate(x, y);
                    ctx.rotate(angle * Math.PI/180);
                }
                ctx.drawImage(image, 0, 0, image.width, image.height);
                ctx.restore();
                _this.uploadImage();
            };
            image.src = src;
        },
        resizeImage: function(image, iwidth, iheight) {
            var _this = this;
            if (image.width / image.height >= iwidth / iheight) {
                if (image.width > iwidth) {
                    image.height = (image.height * iwidth) / image.width;
                    image.width = iwidth;
                }
            } else {
                if (image.height > iheight) {
                    image.width = (image.width * iheight) / image.height;
                    image.height = iheight;
                }
            }
        },
        uploadImage: function() {
            var _this = this;
            var fileName = 'reco.png';
            var canvas = document.getElementById("imageCvs");
            var imagedata = canvas.toDataURL("image/png");
            if ((imagedata.length >> 10) > 200){
                var image = new Image();
                image.onload = function() {
                    var data = jic.compress(image, 50, "png").src;
                    _this.uploadScanImage(data);
                };
                image.src = imagedata;
            }else{
                _this.uploadScanImage(imagedata);
            }
        },
        getUserMedia: function() {
            var _this = this;
            var cameraCount = 0;
            _this.backCameras = [];
            _this.cameras = [];
            navigator.mediaDevices.enumerateDevices().then(function(devices) {
                if(typeof devices !== "undefined") {
                    for(var i = 0; i < devices.length; ++i) {
                        if(devices[i].kind == "videoinput") {
                            ++cameraCount;
                            _this.cameras.push(devices[i]);
                            $('#comment').append("</br>" + devices[i]);
                            if(devices[i].facingMode == "environment" || devices[i].label.indexOf("facing back") >= 0) {
                                _this.backCameras.push(devices[i].deviceId);
                            }
                        }
                    }
                    if(_this.cameras.length > 0 && _this.backCameras.length == 0) {
                        _this.backCameras.push(_this.cameras[0].deviceId);
                    }
                } else {
                    _this.selectImage();
                }
                if(cameraCount == 0) {
                    _this.selectImage();
                } else {
                    if( !_this.deviceIsMobile ) {
                        _this.constraints = {
                            audio: false,
                            video: {
                                frameRate: {
                                    max:    15
                                }
                            }
                        };
                    } else {
                        if(_this.deviceIsAndroid) {
                            _this.constraints = {
                                audio: false,
                                video: {
                                    frameRate: {
                                        max:    15
                                    },
                                    deviceId: _this.backCameras[0]
                                }
                            };
                        } else {
                            _this.constraints = {
                                audio: false,
                                video: {
                                    frameRate: {
                                        max:    15
                                    },
                                    facingMode: {
                                        exact: "environment"
                                    }
                                }
                            };
                        }
                    }
                    _this.displayUserMedia();
                }
            });
        },
        displayUserMedia: function() {
            var _this = this;
            _this.timeCheck = true;
            _this.mediaCheck = false;
            setTimeout(function() {
                if(!_this.mediaCheck) {
                    _this.timeCheck = false;
                    _this.selectImage();
                }
            }, 2000);
            navigator.mediaDevices.getUserMedia(_this.constraints).then(function(mediaStream) {
                if(_this.timeCheck) {
                    _this.mediaCheck = true;
                    _this.onSuccess(mediaStream);
                }
            }).catch(function(err) {
                if(_this.timeCheck) {
                    _this.mediaCheck = true;
                    _this.onError(err);
                }
            });
        },
        onSuccess: function(stream) {
            var _this = this;
            var video = $("video" + _this.target)[0];
            _this.stream = stream;
            _this.isWebRTC = true;

            video.style.opacity = 1;
            video.srcObject = stream;

            video.onloadedmetadata = function() {
                video.play();
                if(typeof $(video).height() == "undefined" || $(video).height() == "" || $(video).height() < 100) {
                    _this.clipScreenAllowed = false;
                    _this.selectImage();
                } else {
                    $("canvas#screen").attr("height", $(video).height()).attr("width", $(video).width());
                    _this.clipScreenAllowed = true;
                    _this.clipScreen();
                    if(_this.openCameraControl && _this.cameras.length > 1) {
                        _this.cameraControl();
                    }
                }
            };
        },
        onError: function(err) {
            var _this = this;
            if(typeof err !== "undefined" && typeof err.name !== "undefined" && err.name !== "") {
                switch (err.name.toLowerCase()) {
                    case "notallowederror":
                        _this.toggleLoadingStatus("hide", "请允许浏览器访问相机");
                        break;
                    default:
                        _this.toggleLoadingStatus("hide", err);
                }
            } else {
                _this.toggleLoadingStatus("hide", (JSON.stringify(err) || "WebRTC ERROR"));
            }
        },
        clipScreen: function() {
            var _this = this;
            if(_this.clipScreenAllowed == false) {
                return false;
            }
            if(_this.scanCount <= _this.maxScanCount) {
                var video = document.querySelector("video" + _this.target);
                var canvas = document.querySelector("canvas#screen");
                var ctx = canvas.getContext("2d");

                ctx.drawImage(video, 0, 0);
                ++_this.scanCount;

                _this.isWebRTC = true;
                var fileReader = new FileReader();

                var imagedata = canvas.toDataURL("image/jpeg");
                if ((imagedata.length >> 10) > 200) {
                    var image = new Image();
                    image.onload = function() {
                        var data = jic.compress(image, 50, "jpeg").src;
                        _this.uploadScanImage(data);
                    };
                    image.src = imagedata;
                } else {
                    _this.uploadScanImage(imagedata);
                }
            } else {
                _this.toggleLoadingStatus("hide", "请对准识别物重新扫描");
                _this.scanCount = 0;
                setTimeout(function() {
                    $("p").text("将AR图放入框中,即可自动扫描");
                    _this.clipScreen();
                }, _this.delay);
            }
        },
        uploadScanImage: function(dataURL) {
            var _this = this;
            var render = false;
            var pass = false;
            var renderData = [];
            $(".loading-shell").removeClass("null");
            if(!_this.isWebRTC) {
                $("#photo").text("正在上传...");
            }
            $.ajax({
                url:        _this.recoApi,
                type:       "POST",
                dataType:   "JSON",
                data: {
                    image:  dataURL.replace("data:image/jpeg;base64,", "").replace("data:image/png;base64,", ""),
                    key:    _this.key
                },
                error: function(xhr) {
                    pass = true;
                    _this.toggleLoadingStatus("hide", "网络异常");
                },
                success: function(result) {
                    //$("#test-image").remove();
                    //$("body").append("<img id='test-image' src='" + dataURL + "'/>");
                    switch (result.retCode) {
                        case 0:
                            if(+result.items[0].score < 10) {
                                if(_this.isWebRTC) {
                                    pass = true;
                                } else {
                                    pass = false;
                                    $(".loading-shell").addClass("null");
                                }
                            } else {
                                render = true;
                                renderData = result.items[0].resources;
                            }
                            break;
                        case 1005:
                        case 1019:
                            if(_this.isWebRTC) {
                                pass = true;
                            } else {
                                pass = false;
                                $(".loading-shell").addClass("null");
                            }
                            break;
                        //case 1001:
                        //case 1002:
                        //case 3002:
                        //    _this.toggleLoadingStatus("hide", result.comment);
                        //    break;
                        default:
                            _this.toggleLoadingStatus("hide", result.comment);
                    }
                },
                complete: function() {
                    if(!_this.isWebRTC) {
                        $("#photo").text("拍图扫描");
                    }
                    if((!render) && pass && _this.isWebRTC) {
                        setTimeout(function() {
                            _this.clipScreen();
                        }, _this.delay);
                    } else {
                        if(render) {
                            $("#photo").text("正在渲染...");
                            _this.renderResult(renderData);
                        }
                    }
                }
            });
        },
        cameraControl: function() {
            var _this = this;
            var camerasStr = "<div><div class='before'></div><div class='after'></div></div>";
            var name = "";
            var id = "";

            if($("#cameraControl").length == 0) {
                $("body").append("<div id='cameraControl'>" + camerasStr + "</div>");
            }
            $("#cameraControl").off().on("click", function(e) {
                e.stopPropagation();
                $("#cameraControl").toggleClass("active");

                var video = document.querySelector("video" + _this.target);
                video.pause();
                _this.clipScreenAllowed = false;
                if(_this.cameras.length < 2) {
                    return false;
                }
                if(_this.deviceIsMobile) {
                    _this.stream.getTracks()[0].stop();
                    _this.maxScanCount = 100;
                    if(_this.deviceIsAndroid) {
                        id = "";
                        if(_this.cameras[0].deviceId == _this.backCameras[0]) {
                            id = _this.cameras[1].deviceId;
                        } else {
                            id = _this.cameras[0].deviceId;
                        }
                        _this.backCameras[0] = id;
                        _this.constraints = {
                            audio: false,
                            video: {
                                frameRate: {
                                    max:    15
                                },
                                deviceId: id
                            }
                        };
                    } else {
                        _this.constraints = {
                            audio: false,
                            video: {
                                frameRate: {
                                    max:    15
                                },
                                facingMode: {
                                    exact: (_this.constraints.video.facingMode.exact == "environment") ? "user" : "environment"
                                }
                            }
                        };
                    }
                    _this.displayUserMedia();
                }
            });
        },
        toggleLoadingStatus: function(type, info) {
            var _this = this;
            if(typeof info !== "undefined" && info != "") {
                if(typeof info !== "undefined" && info != "") {
                    if(typeof info == "object") {
                        info = info.name
                    }
                    if(typeof info !== "string" && info.indexOf('"') > -1) {
                        info = info.replace(/\"/g, "");
                    }
                }
            }
            switch (type) {
                case "hide":
                    $(".loading-line").removeClass("active");
                    $("p").text(info);
                    setTimeout(function() {
                        alert(info);
                    }, 0);
                    break;
                case "active":
                    $(".loading-shell").show();
                    $(".loading-line").addClass("active");
                    $("p").text(info);
                    break;
                case "model":
                    $(".loading-shell, p").hide();
                    $("body").find("#photo").hide();
                    break;
                case "render":
                    $(".loading-shell, p").hide();
                    $(".mask").show();
                    $("button#scanBtn").off().on("click", function(e) {
                        e.stopPropagation();
                        $(".loading-shell, p").show();
                        $(".loading-line").removeClass("active");
                        $(".mask").hide();
                        $("p").text("将AR图放入框中,即可自动扫描");
                        $(".mask > video.player")[0].pause();
                        $(".mask > video.player").trigger('pause');
                        $(".mask > video.player").remove();
                        $(".mask").prepend('<video class="player" src="" preload="auto" controls webkit-playsinline="true" playsinline="true" ' +
                            'x-webkit-airplay="allow" x5-video-player-type="h5" ' +
                            'x5-video-player-fullscreen="true" ' +
                            'x5-video-orientation="portraint"></video>');
                        _this.scanCount = 0;
                        setTimeout(function() {
                            if(_this.isWebRTC) {
                                _this.clipScreen();
                            } else {
                                _this.selectImage();
                            }
                        }, _this.delay);
                    });
                    break;
            }
        },
        renderResult: function(data) {
            var _this = this;
            var count = 0;
            var renderModel = false;
            var renderHref = "";
            var renderVideo = "";
            var modelsData = [];
            if(data.length == 0) {
                setTimeout(function() {
                    _this.scanCount = 0;
                    _this.clipScreen();
                }, _this.delay);
            } else {
                for(var i= 0; i < data.length; ++i) {
                    switch (data[i].sourceType) {
                        case 1:
                            renderHref = data[i].data.content;
                            ++count;
                            break;
                        case 3:
                            renderVideo = data[i].data.content;
                            ++count;
                            break;
                        case 12:
                            renderModel = true;
                            modelsData = data[i].data.objects;
                            count = 3;
                            break;
                    }
                }
                if(count == 0) {
                    if(_this.isWebRTC) {
                        setTimeout(function() {
                            _this.scanCount = 0;
                            _this.clipScreen();
                        }, _this.delay);
                    } else {
                        _this.toggleLoadingStatus("hide", "请对准识别物重新拍照");
                        _this.selectImage();
                    }
                } else if(count == 1) {
                    _this.toggleLoadingStatus("active", "识别成功!");
                    if(renderHref != "") {
                        location.href = renderHref
                    } else {
                        location.href = renderVideo;
                    }
                } else {
                    if(renderModel) {
                        _this.toggleLoadingStatus("active", "");
                        _this.getDomain(modelsData);
                        //_this.addRefresh();
                    } else {
                        $(".mask > div > a").attr("href", renderHref);
                        $(".mask > video.player").attr("src", renderVideo);
                        $("#photo").hide();
                        setTimeout(function() {
                            _this.toggleLoadingStatus("render", "");
                        }, 0);
                    }
                }
            }
        },
        addRefresh: function() {
            var _this = this;
            $("#refreshButton").remove();
            $("body").append("<div id='refreshButton'><</div>");
            setTimeout(function() {
                $("#refreshButton").off().on("click", function(e) {
                    e.stopPropagation();
                    $(".loading-shell, p").show();
                    $(".loading-line").removeClass("active");
                    $(".mask").hide();
                    $("canvas:not(#imageCvs, #screen)").remove();
                    $("p").text("将AR图放入框中,即可自动扫描");
                    _this.scanCount = 0;
                    setTimeout(function() {
                        if(_this.isWebRTC) {
                            _this.clipScreen();
                        } else {
                            _this.selectImage();
                        }
                    }, _this.delay);
                });
            }, 0);
        },
        getDomain: function(modelsData) {
            var _this = this;
            _this.toggleLoadingStatus("active", "");
            $.ajax({
                url: _this.domainApi,
                type: "GET",
                dataType: 'json',
                async:true,
                error: function () {
                    _this.toggleLoadingStatus("hide", "网络异常");
                },
                success: function (result) {
                    switch (result.retCode) {
                        case 0:
                            _this.toggleLoadingStatus("active", "");
                            _this.resourceDomain = result.domain;
                            _this.initScene(modelsData);
                            break;
                        default:
                            _this.toggleLoadingStatus("hide", result.comment);
                    }
                }
            });

        },
        initScene: function(data) {
            var _this = this;
            _this.objects = [];
            _this.toggleLoadingStatus("active", "");
            var length = data.length;
            _this.camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 10, 10000);
            var scene = new THREE.Scene();
            var renderer = new THREE.WebGLRenderer({
                alpha:true,
                antialias: true
            });
            var ambientLight = new THREE.AmbientLight(0xffffff);
            var directionalLight = new THREE.DirectionalLight(0xffffff, 0.1);
            var controls = new THREE.OrbitControls(_this.camera);

            _this.camera.position.set(500, 700, 500);
            _this.camera.lookAt(new THREE.Vector3());
            directionalLight.rotationX = 90;

            _this.renderCount = 0;
            for(var j = 0; j < length; ++j) {
                switch (data[j].materialType) {
                    case 1:
                    case 2:
                    case 3:
                    case 4:
                    case "videoGroup":
                    case 5:
                    case 6:
                        ++_this.renderCount;
                        break;
                }
            }
            for(var i = 0; i < length; ++i) {
                switch (data[i].materialType) {
                    case 1:
                        _this.renderWebModel(data[i], scene);
                        break;
                    case 2:
                        _this.renderImageModel(data[i], scene);
                        break;
                    case 3:
                    case "videoGroup":
                        _this.renderVideoModel(data[i], scene);
                        break;
                    case 4:
                        _this.renderMusicModel(data[i], scene);
                        break;
                    case 5:
                        _this.renderTextModel(data[i], scene);
                        break;
                    case 6:
                        _this.renderFBXModel(data[i], scene);
                        break;
                }
            }

            scene.add(ambientLight);
            scene.add(directionalLight);

            renderer.setSize(document.body.offsetWidth, document.body.offsetHeight);
            document.body.appendChild( renderer.domElement );

            checkRender();

            window.addEventListener("orientationchange", function() {
                setTimeout(function() {
                    renderer.setSize(document.body.offsetWidth, document.body.offsetHeight);
                    render();
                }, 400);
            }, false);

            if(_this.interactingSupport) {
                _this.addObjectInteracte();
            }

            function checkRender() {
                if(_this.renderCount == 0) {
                    render();
                    if(_this.audio != null) {
                        _this.audio.play();
                    }
                    clearTimeout(checkRender);
                    return false;
                } else {
                    setTimeout(function() {
                        checkRender();
                    }, 200);
                }
            }

            function render() {
                requestAnimationFrame( render );
                renderer.render(scene, _this.camera);
                _this.toggleLoadingStatus("model", "");
            }
        },
        addObjectInteracte: function() {
            var _this = this;
            var mouse = new THREE.Vector2();
            var raycaster = new THREE.Raycaster();
            var onDownPosition = new THREE.Vector2();
            var onUpPosition = new THREE.Vector2();
            var onDoubleClickPosition = new THREE.Vector2();

            function getIntersects(point, objects) {

                mouse.set(( point.x * 2 ) - 1, -( point.y * 2 ) + 1);
                raycaster.setFromCamera(mouse, _this.camera);
                return raycaster.intersectObjects(objects);
            }

            function getMousePosition(dom, x, y) {
                var rect = dom.getBoundingClientRect();
                return [( x - rect.left ) / rect.width, ( y - rect.top ) / rect.height];
            }

            function handleClick() {

                if (onDownPosition.distanceTo(onUpPosition) === 0) {

                    var intersects = getIntersects(onDownPosition, _this.objects);

                    if(intersects.length > 0) {

                        var object = intersects[0].object;
                        if(object.name == "Object004") {
                            window.open("http://www.hiscene.com");
                        }

                    }
                }
            }
            document.removeEventListener('touchend', onTouchEnd, false);
            document.addEventListener('touchend', onTouchEnd, false);
            document.removeEventListener('mouseup', onMouseUp, false);
            document.addEventListener('mouseup', onMouseUp, false);
            document.addEventListener('mousedown', onMouseDown, false);

            function onTouchEnd(event) {
                var touch = event;
                if(typeof event.changedTouches !== "undefined") {
                    touch = event.changedTouches[0];
                }
                var array = getMousePosition($("body")[0], touch.clientX, touch.clientY);
                onDownPosition.fromArray(array);

                handleClick();

                document.removeEventListener('touchend', onTouchEnd, false);
            }
            function onMouseDown(event) {
                event.preventDefault();

                var array = getMousePosition($("body")[0], event.clientX, event.clientY);
                onDownPosition.fromArray(array);
                document.addEventListener('mouseup', onMouseUp, false);
            }
            function onMouseUp(event) {
                var array = getMousePosition($("body")[0], event.clientX, event.clientY);
                onUpPosition.fromArray(array);
                handleClick();

                document.removeEventListener('mouseup', onMouseUp, false);
            }
        },
        renderVideoModel: function(data, scene) {
            var _this = this;
            var video = document.createElement('video');
            var url = data.content;
            var cav = document.createElement('canvas');
            var ctx = cav.getContext('2d');
            var texture, geometry, material, mesh;

            video.crossOrigin = '';

            if(_this.resourceDomain != "") {
                if(url.indexOf(_this.resourceDomain) != 0) {
                    $.ajax({
                        url: _this.transformVideoApi,
                        dataType: 'json',
                        type: 'POST',
                        async: false,
                        data: {
                            url: encodeURIComponent(url)
                        },
                        error: function() {
                            _this.toggleLoadingStatus("hide", "网络异常");
                        },
                        success: function(result) {
                            switch (result.retCode) {
                                case 0:
                                    url = "/api/editor/transformvideo?key=" + result.value;
                                    addUrlToVideo();
                                    break;
                                default:
                                    _this.toggleLoadingStatus("hide", result.comment);
                            }
                        }
                    })
                } else {
                    url = url.replace(_this.resourceDomain, "");
                    if(url[0] == "/") {
                        url = url.substring(1);
                    }
                    addUrlToVideo();
                }
            }

            function addUrlToVideo() {
                video.src = url;
                video.autobuffer = true;
                video.loop = data.isLoopPlay || true;
                video.type = "video";

                if(_this.deviceIsMobile) {
                    --_this.renderCount;
                }
                video.onloadedmetadata = function () {
                    video.play();
                    texture = new THREE.VideoTexture(video);
                    texture.minFilter = THREE.LinearFilter;
                    texture.magFilter = THREE.LinearFilter;
                    texture.format = THREE.RGBFormat;
                    texture.needsUpdate = true;
                    geometry = new THREE.PlaneGeometry(video.videoWidth, video.videoHeight);
                    material = new THREE.MeshBasicMaterial({map: texture, overdraw: true, side: THREE.DoubleSide});
                    mesh = new THREE.Mesh(geometry, material);
                    mesh.position.set(0, 0, 0);
                    mesh.rotation.set(data.rotationX * THREE.Math.DEG2RAD, data.rotationY * THREE.Math.DEG2RAD, data.rotationZ * THREE.Math.DEG2RAD); // Math.PI / 180
                    mesh.scale.set(data.scaleX, data.scaleY, data.scaleZ);

                    scene.add(mesh);
                    --_this.renderCount;
                };
            }
        },
        testCode: function(info) {
            var _this = this;
            if(typeof info === "object") {
                info = JSON.stringify(info);
            }
            if($("#test").length == 0) {
                $("body").append("<div id='test'></div>");
            }
            $("#test").append(info + "<br>");
        },
        renderTextModel: function(data, scene) {
            var _this = this;
            var texture = _this.createTextTextaure(data);
            var geometry = new THREE.PlaneGeometry(texture.image.width, texture.image.height);
            var material = new THREE.MeshBasicMaterial({map: texture, side: THREE.DoubleSide});
            material.transparent = true;
            var mesh = new THREE.Mesh(geometry, material);
            mesh.position.set(data.positionX || 0, data.positionY || 10, data.positionZ || 0);
            mesh.rotation.set(data.rotationX * THREE.Math.DEG2RAD || -(Math.PI / 2), data.rotationY * THREE.Math.DEG2RAD || 0, data.rotationZ * THREE.Math.DEG2RAD || 0);
            mesh.scale.set(data.scaleX || 1, data.scaleY || 1, data.scaleZ || 1);

            scene.add(mesh);
            --_this.renderCount;
        },
        createTextTextaure: function(textInfo) {
            var _this = this;
            var cav = document.createElement('canvas');
            var ctx = cav.getContext('2d');
            ctx.font = textInfo.size + "px " + textInfo.font;
            var textWidth = ctx.measureText(textInfo.content).width;
            var height = 4 * textInfo.size / 3;
            cav.width = textWidth;
            cav.height = height;
            ctx.fillStyle = textInfo.color;
            ctx.font = textInfo.size + "px " + textInfo.font;
            ctx.fillText(textInfo.content, 0, textInfo.size);
            var texture = new THREE.Texture(cav);
            texture.needsUpdate = true;
            return texture;
        },
        renderImageModel: function(data, scene) {
            var _this = this;
            var loader = new THREE.ImageLoader();
            var url = data.content;
            if (_this.resourceDomain != "") {
                url = data.content.replace(_this.resourceDomain, "");
                if(url[0] == "/"){
                    url = url.substring(1);
                }
            }

            loader.load(url,
                function (image) {
                    var cav = document.createElement('canvas');
                    cav.width = image.width;
                    cav.height = image.height;
                    var ctx = cav.getContext('2d');
                    ctx.drawImage(image, 0, 0, image.width, image.height);
                    var texture = new THREE.Texture(cav);
                    texture.needsUpdate = true;
                    var material = new THREE.MeshBasicMaterial({map: texture, side: THREE.DoubleSide});
                    material.transparent = true;
                    var mesh = new THREE.Mesh(new THREE.PlaneGeometry(cav.width, cav.height), material);
                    mesh.position.set(data.positionX || 0, data.positionY || 10, data.positionZ || 0);
                    mesh.rotation.set(data.rotationX * THREE.Math.DEG2RAD || -(Math.PI / 2), data.rotationY * THREE.Math.DEG2RAD || 0, data.rotationZ * THREE.Math.DEG2RAD || 0);
                    mesh.scale.set(data.scaleX || 1, data.scaleY || 1, data.scaleZ || 1);

                    scene.add(mesh);
                    --_this.renderCount;
                }
            );
        },
        renderWebModel: function(data, scene) {
            var _this = this;
            var texture = _this.createHrefTextaure(data);
            var geometry = new THREE.PlaneGeometry(texture.image.width, texture.image.height);
            var material = new THREE.MeshBasicMaterial({map: texture, side: THREE.DoubleSide});
            material.transparent = true;
            var mesh = new THREE.Mesh(geometry, material);
            mesh.position.set(data.positionX || 0, data.positionY || 10, data.positionZ || 0);
            mesh.rotation.set(data.rotationX * THREE.Math.DEG2RAD || -(Math.PI / 2), data.rotationY * THREE.Math.DEG2RAD || 0, data.rotationZ * THREE.Math.DEG2RAD || 0);
            mesh.scale.set(data.scaleX || 1, data.scaleY || 1, data.scaleZ || 1);

            scene.add(mesh);
            --_this.renderCount;
        },
        createHrefTextaure: function(hrefInfo) {
            var _this = this;
            var cav = document.createElement('canvas');
            var ctx = cav.getContext('2d');
            ctx.font = hrefInfo.size + "px " + hrefInfo.font;
            var textWidth = ctx.measureText(hrefInfo.content).width;
            var height = 4 * hrefInfo.size / 3;
            cav.width = textWidth;
            cav.height = height;
            if (hrefInfo.displayBackground) {
                ctx.fillStyle = hrefInfo.backgroundColor;
                ctx.fillRect(0, 0, cav.width, cav.height);
                ctx.stroke();
            }
            ctx.fillStyle = hrefInfo.color;
            ctx.font = hrefInfo.size + "px " + hrefInfo.font;
            ctx.fillText(hrefInfo.content, 0, hrefInfo.size);
            var texture = new THREE.Texture(cav);
            texture.needsUpdate = true;
            return texture;
        },
        renderMusicModel: function(data, scene) {
            var _this = this;
            var audio = document.createElement("audio");
            var url = data.content;
            if(_this.resourceDomain != ""){
                url = url.replace(_this.resourceDomain, "");
                if(url[0] == "/"){
                    url = url.substring(1);
                }
            }
            audio.src = url;
            audio.audiobuffer = true;
            audio.loop = !!data.isLoopPlay;
            --_this.renderCount;

            audio.onloadedmetadata = function () {
                _this.audio = audio;
            }
        },
        renderFBXModel: function(data, scene) {
            var _this = this;
            var mixers = [];
            var clocks = [];
            var loader, model;
            var manager = new THREE.LoadingManager();

            if(_this.resourceDomain != "") {
                model = data.model.replace(_this.resourceDomain, "");
            }
            manager.onProgress = function (item, loaded, total) {
                _this.toggleLoadingStatus("active", "");
            };
            var onProgress = function ( xhr ) {
                if ( xhr.lengthComputable ) {
                    var percentComplete = xhr.loaded / xhr.total * 100;
                    if((Math.round(percentComplete, 2)) < 100) {
                        _this.toggleLoadingStatus("active", "");
                        $(".loading-shell > span").text("模型加载中..." + (Math.round(percentComplete, 2)) + "%");
                    } else {
                        _this.toggleLoadingStatus("model", "");
                    }
                }
            };
            var onError = function ( xhr ) {
                console.warn(xhr);
                --_this.renderCount;
            };
            loader = new THREE.FBXLoader(manager);
            loader.load(model, function(object) {
                object.position.set(data.positionX || 0, data.positionY || 0, data.positionZ || 0);
                object.rotation.set(data.rotationX * THREE.Math.DEG2RAD || 0, data.rotationY * THREE.Math.DEG2RAD || 0, data.rotationZ * THREE.Math.DEG2RAD || 0);
                object.scale.set(data.scaleX || 1, data.scaleY || 1, data.scaleZ || 1);

                object.mixer = new THREE.AnimationMixer(object);
                mixers.push(object.mixer);
                clocks.push(new THREE.Clock());

                if(object.animations.length > 0) {
                    var action = object.mixer.clipAction( object.animations[0] );
                    action.play();
                }

                scene.add(object);
                if(_this.interactingSupport) {
                    if(object.children.length > 0) {
                        for(var i = 0; i < object.children.length; ++i) {
                            _this.objects.push(object.children[i]);
                        }
                    } else {
                        _this.objects.push(object);
                    }
                }
                --_this.renderCount;
            }, onProgress, onError);

            animate();

            function animate() {
                requestAnimationFrame(animate);
                if(mixers.length > 0) {
                    for(var i = 0; i < mixers.length; ++i) {
                        mixers[i].update(clocks[i].getDelta());
                    }
                } else {
                    return false;
                }
            }
        }
    };

    SupportComponent.fn.init.prototype = SupportComponent.fn;

    return SupportComponent;
})();
上一篇下一篇

猜你喜欢

热点阅读