js封装

作者: 海货 | 来源:发表于2018-12-28 10:04 被阅读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;
    })();
    

    相关文章

      网友评论

          本文标题:js封装

          本文链接:https://www.haomeiwen.com/subject/jhfslqtx.html