IT俱乐部 HTML5 HTML+CSS+JavaScript实现图片3D展览的示例代码

HTML+CSS+JavaScript实现图片3D展览的示例代码

一、图片3D展览效果

上传图片的大小有限制,录制的GIF图展示效果不是很好

录屏的效果见链接:https://www.bilibili.com/video/BV1Bi4y1E7wk/

二、代码实现

1. HTML代码




    图片3D展览屋
        html
        {
            overflow:visible;
            -ms-touch-action: none;
            -ms-content-zooming: none;
        }
        body
        {
            position: absolute;
            margin: 0px;
            padding: 0px;
            background: #fff;
            width: 100%;
            height: 100%;
        }
        #canvas
        {
            position: absolute;
            width: 100%;
            height: 100%;
            background: #fff;
        }
    

        "use strict";

        (function () {
            /* ==== definitions ==== */
            var diapo = [], layers = [], ctx, pointer, scr, camera, light, fps = 0, quality = [1, 2],
            // ---- poly constructor ----
	Poly = function (parent, face) {
	    this.parent = parent;
	    this.ctx = ctx;
	    this.color = face.fill || false;
	    this.points = [];
	    if (!face.img) {
	        // ---- create points ----
	        for (var i = 0; i  1500) ? quality[0] : quality[1];
	                        d.img.setLevel(lev);
	                    }
	                }
	            }
	        }
	    });
	    // ---- init camera ----
	    camera = new ge1doot.transform3D.Camera({
	        focalLength: Math.sqrt(scr.width) * 10,
	        easeTranslation: 0.025,
	        easeRotation: 0.06,
	        disableRz: true
	    }, {
	        move: function () {
	            this.over = false;
	            // ---- rotation ----
	            if (pointer.isDraging) {
	                this.target.elem = false;
	                this.target.ry = -pointer.Xi * 0.01;
	                this.target.rx = (pointer.Y - scr.height * 0.5) / (scr.height * 0.5);
	            } else {
	                if (this.target.elem) {
	                    this.target.ry = Math.atan2(
							this.target.elem.pc.x - this.x,
							this.target.elem.pc.z - this.z
						);
	                }
	            }
	            this.target.rx *= 0.9;
	        }
	    });
	    camera.z = -10000;
	    camera.py = 0;
	    // ---- create images ----
	    for (var i = 0, img; img = json.imgdata[i++]; ) {
	        diapo.push(
				new Diapo(
					json.options.imagesPath,
					img,
					json.structure
				)
			);
	    }
	    // ---- start engine ---- >>>
	    setInterval(function () {
	        quality = (fps > 50) ? [2, 3] : [1, 2];
	        fps = 0;
	    }, 1000);
	    run();
	},
            // ---- main loop ----
	run = function () {
	    // ---- clear screen ----
	    ctx.clearRect(0, 0, scr.width, scr.height);
	    // ---- camera ----
	    camera.move();
	    // ---- draw layers ----
	    for (var k = -1, l; l = layers[++k]; ) {
	        light = false;
	        for (var i = 0, d; d = diapo[i++]; ) {
	            (l === 1 && d.draw()) ||
				(d.visible && d.poly[k].draw());
	        }
	    }
	    // ---- cursor ----
	    if (camera.over && !pointer.isDraging) {
	        scr.setCursor("pointer");
	    } else {
	        scr.setCursor("move");
	    }
	    // ---- loop ----
	    fps++;
	    requestAnimFrame(run);
	};
            /* ==== prototypes ==== */
            Poly.prototype.draw = function () {
                // ---- color light ----
                var c = this.color;
                if (c.light || !light) {
                    var s = c.light ? this.parent.light : 1;
                    // ---- rgba color ----
                    light = "rgba(" +
				Math.round(c.r * s) + "," +
				Math.round(c.g * s) + "," +
				Math.round(c.b * s) + "," + (c.a || 1) + ")";
                    ctx.fillStyle = light;
                }
                // ---- paint poly ----
                if (!c.light || this.parent.light < 1) {
                    // ---- projection ----
                    for (
				var i = 0;
				this.points[i++].projection();
			);
                    this.drawPoly();
                    ctx.fill();
                }
            }
            /* ==== image onload ==== */
            Diapo.prototype.loaded = function (img) {
                // ---- create points ----
                var d = [-1, 1, 1, -1, 1, 1, -1, -1];
                var w = img.texture.width * 0.5;
                var h = img.texture.height * 0.5;
                for (var i = 0; i  -(camera.focalLength >> 1) && this.img.transform3D(true)) {
                    // ---- light ----
                    this.light = 0.5 + Math.abs(this.normalZ * camera.cosY - this.normalX * camera.sinY) * 0.6;
                    // ---- draw image ----
                    this.visible = true;
                    this.img.draw();
                    // ---- test pointer inside ----
                    if (pointer.hasMoved || pointer.isDown) {
                        if (
					this.img.isPointerInside(
						pointer.X,
						pointer.Y
					)
				) camera.over = this;
                    }
                } else this.visible = false;
                return true;
            }
            return {
                // --- load data ----
                load: function (data) {
                    window.addEventListener('load', function () {
                        ge1doot.loadJS(
					"res/imageTransform3D.js",
					init, data
				);
                    }, false);
                }
            }
        })().load({
            imgdata: [
            // north
		{img: 'imgs/001.jpg', x: -1000, y: 0, z: 1500, nx: 0, nz: 1 },
		{ img: 'imgs/002.jpg', x: 0, y: 0, z: 1500, nx: 0, nz: 1 },
		{ img: 'imgs/003.jpg', x: 1000, y: 0, z: 1500, nx: 0, nz: 1 },
            // east
		{img: 'imgs/004.jpg', x: 1500, y: 0, z: 1000, nx: -1, nz: 0 },
		{ img: 'imgs/005.jpg', x: 1500, y: 0, z: 0, nx: -1, nz: 0 },
		{ img: 'imgs/006.jpg', x: 1500, y: 0, z: -1000, nx: -1, nz: 0 },
            // south
		{img: 'imgs/007.jpg', x: 1000, y: 0, z: -1500, nx: 0, nz: -1 },
		{ img: 'imgs/008.jpg', x: 0, y: 0, z: -1500, nx: 0, nz: -1 },
		{ img: 'imgs/009.jpg', x: -1000, y: 0, z: -1500, nx: 0, nz: -1 },
            // west
		{img: 'imgs/010.jpg', x: -1500, y: 0, z: -1000, nx: 1, nz: 0 },
		{ img: 'imgs/011.jpg', x: -1500, y: 0, z: 0, nx: 1, nz: 0 },
		{ img: 'imgs/012.jpg', x: -1500, y: 0, z: 1000, nx: 1, nz: 0 }
	],
            structure: [
		{
		    // wall
		    fill: { r: 255, g: 255, b: 255, light: 1 },
		    x: [-1001, -490, -490, -1001],
		    z: [-500, -500, -500, -500],
		    y: [500, 500, -500, -500]
		}, {
		    // wall
		    fill: { r: 255, g: 255, b: 255, light: 1 },
		    x: [-501, 2, 2, -500],
		    z: [-500, -500, -500, -500],
		    y: [500, 500, -500, -500]
		}, {
		    // wall
		    fill: { r: 255, g: 255, b: 255, light: 1 },
		    x: [0, 502, 502, 0],
		    z: [-500, -500, -500, -500],
		    y: [500, 500, -500, -500]
		}, {
		    // wall
		    fill: { r: 255, g: 255, b: 255, light: 1 },
		    x: [490, 1002, 1002, 490],
		    z: [-500, -500, -500, -500],
		    y: [500, 500, -500, -500]
		}, {
		    // shadow
		    fill: { r: 0, g: 0, b: 0, a: 0.2 },
		    x: [-420, 420, 420, -420],
		    z: [-500, -500, -500, -500],
		    y: [150, 150, -320, -320]
		}, {
		    // shadow
		    fill: { r: 0, g: 0, b: 0, a: 0.2 },
		    x: [-20, 20, 20, -20],
		    z: [-500, -500, -500, -500],
		    y: [250, 250, 150, 150]
		}, {
		    // shadow
		    fill: { r: 0, g: 0, b: 0, a: 0.2 },
		    x: [-20, 20, 20, -20],
		    z: [-500, -500, -500, -500],
		    y: [-320, -320, -500, -500]
		}, {
		    // shadow
		    fill: { r: 0, g: 0, b: 0, a: 0.2 },
		    x: [-20, 20, 10, -10],
		    z: [-500, -500, -100, -100],
		    y: [-500, -500, -500, -500]
		}, {
		    // base
		    fill: { r: 32, g: 32, b: 32 },
		    x: [-50, 50, 50, -50],
		    z: [-150, -150, -50, -50],
		    y: [-500, -500, -500, -500]
		}, {
		    // support
		    fill: { r: 16, g: 16, b: 16 },
		    x: [-10, 10, 10, -10],
		    z: [-100, -100, -100, -100],
		    y: [300, 300, -500, -500]
		}, {
		    // frame
		    fill: { r: 255, g: 255, b: 255 },
		    x: [-320, -320, -320, -320],
		    z: [0, -20, -20, 0],
		    y: [-190, -190, 190, 190]
		}, {
		    // frame
		    fill: { r: 255, g: 255, b: 255 },
		    x: [320, 320, 320, 320],
		    z: [0, -20, -20, 0],
		    y: [-190, -190, 190, 190]
		},
		{ img: true },
		{
		    // ceilingLight
		    fill: { r: 255, g: 128, b: 0 },
		    x: [-50, 50, 50, -50],
		    z: [450, 450, 550, 550],
		    y: [500, 500, 500, 500]
		}, {
		    // groundLight
		    fill: { r: 255, g: 128, b: 0 },
		    x: [-50, 50, 50, -50],
		    z: [450, 450, 550, 550],
		    y: [-500, -500, -500, -500]
		}
	],
            options: {
                imagesPath: ""
            }
        });
CSDN文章
建议用谷歌浏览器打开

2. CSS代码

#icon {
	background: rgb(255, 144, 0); border-radius: 6px 0px 0px; transition:0.6s ease-in-out; left: 65px; top: 6px; width: 40px; height: 40px; overflow: hidden; position: relative; cursor: pointer; -moz-transition: all 0.6s ease-in-out 0s; -webkit-transition: all 0.6s ease-in-out 0s; -o-transition: all 0.6s ease-in-out 0s;
}
#icon div {
	background: none; position: absolute;
}
#icon div:nth-child(1) {
	border-width: 7px 0px 7px 8px; border-style: solid; border-color: transparent rgb(255, 255, 255); left: 20px; top: 50%; width: 0px; height: 0px; margin-top: -7px; position: absolute;
}
#icon div:nth-child(2) {
	background: rgb(255, 255, 255); left: 12px; top: 50%; width: 8px; height: 6px; margin-top: -3px; position: absolute;
}
#nav {
	top: 10px; width: 100px; height: 0px; position: absolute; -ms-user-select: none; -webkit-user-select: none; -moz-user-select: none;
}
#nav-switch {
	display: none;
}
#nav .label {
	display: block; cursor: pointer;
}
#nav .container {
	transition:left 0.3s ease-in-out; left: -100px; width: 100%; position: absolute; -moz-transition: left 0.3s ease-in-out 0s; -webkit-transition: left 0.3s ease-in-out 0s; -o-transition: left 0.3s ease-in-out 0s;
}
#nav .container > div {
	padding: 0px; width: 50%; float: left;
}
#nav .container .nav-on {
	color: rgb(51, 51, 51); padding-left: 0px;
}
#nav .container .nav-off {
	width: 40px; height: 40px; padding-right: 10px;
}
:checked#nav-switch + .label .container {
	left: 10px;
}
:checked#nav-switch + .label #icon {
	background: rgb(0, 101, 203); border-radius: 0px 0px 6px; transform: rotate(-180deg); -webkit-transform: rotate(-180deg); -moz-transform: rotate(-180deg); -o-transform: rotate(-180deg);
}
.title {
	margin: 0px; padding: 0px; left: 170px; top: 2px; height: 40px; color: rgb(51, 51, 51); line-height: 40px; font-family: "Segoe UI Light", "Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif; font-size: 24px; font-weight: bold; white-space: nowrap; position: absolute; -ms-user-select: none; -webkit-user-select: none; -moz-user-select: none; -o-user-select: none; user-select: none;
}
.menu {
	margin: 0px; padding: 0px; left: 0px; top: 6px; color: rgb(51, 51, 51); font-family: "Segoe UI Light", "Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif; font-size: 1em; font-weight: lighter; list-style-type: none; position: relative; cursor: pointer;
}
.menu li {
	list-style: none; width: 100px; height: 40px; border-right-color: rgb(221, 221, 221); border-right-width: 1px; border-right-style: solid; position: relative; cursor: pointer;
}
.menu a {
	color: rgb(51, 51, 51); line-height: 40px; padding-left: 40px; text-decoration: none; display: block; position: relative;
}
.menu li a:hover {
	background: rgb(255, 144, 0);
}
.menu li a:focus {
	background: rgb(255, 144, 0);
}
.menu li a:active {
	background: rgb(255, 144, 0);
}
#nav li::before {
	top: 50%; margin-left: 10px; position: absolute; content: "";
}
#nav li::after {
	top: 50%; margin-left: 10px; position: absolute; content: "";
}
#nav li a::before {
	top: 50%; margin-left: 10px; position: absolute; content: "";
}
#nav li a::after {
	top: 50%; margin-left: 10px; position: absolute; content: "";
}
#nav .home a::before {
	border-width: 8px 7px; border-style: solid; border-color: transparent transparent rgb(51, 51, 51); left: 2px; margin-top: -16px;
}
#nav .home a::after {
	border-width: 3px 4px 0px; border-style: solid; border-color: rgb(51, 51, 51) rgb(51, 51, 51) transparent; left: 4px; width: 2px; height: 4px; margin-top: 0px;
}
#nav .arrow a::before {
	border-width: 7px 0px 7px 8px; border-style: solid; border-color: transparent rgb(51, 51, 51); left: 8px; margin-top: -7px;
}
#nav .arrow a::after {
	background: rgb(51, 51, 51); left: 0px; width: 8px; height: 6px; margin-top: -3px;
}
#nav .back.arrow a::before {
	border-width: 7px 8px 7px 0px; left: 0px;
}
#nav .back.arrow a::after {
	left: 8px;
}
#nav .list a::before {
	background: none; border-width: 6px 0px; border-style: double; border-color: rgb(51, 51, 51); left: 5px; top: 14px; width: 12px; height: 2px;
}
#nav .list a::after {
	background: none; border-width: 6px 0px; border-style: double; border-color: rgb(51, 51, 51); left: 1px; top: 14px; width: 2px; height: 2px;
}

3. JavaScript代码

// ===== ge1doot global =====    js文件1
var ge1doot = ge1doot || {
	json: null,
	screen: null,
	pointer: null,
	camera: null,
	loadJS: function (url, callback, data) {
		if (typeof url == "string") url = [url];
		var load = function (src) {
			var script = document.createElement("script");
				if (callback) {
					if (script.readyState){
						script.onreadystatechange = function () {
							if (script.readyState == "loaded" || script.readyState == "complete"){
								script.onreadystatechange = null;
								if (--n === 0) callback(data || false);
							}
						}
					} else {
						script.onload = function() {
							if (--n === 0) callback(data || false);
						}
					}
				}
				script.src = src;
				document.getElementsByTagName("head")[0].appendChild(script);
		}
		for (var i = 0, n = url.length; i  11 || Math.abs(this.Y - sY) > 11) {
			this.hasMoved = true;
			if (this.isDown) {
				if (!this.isDraging) {
					this.startX = sX;
					this.startY = sY;
					this.setup.startDrag && this.setup.startDrag(e);
					this.isDraging = true;
				} else {
					this.setup.drag && this.setup.drag(e);
				}
			} else {
				sX = this.X;
				sY = this.Y;
			}
		}
		this.setup.move && this.setup.move(e);
	}
	this.pointerUp = function(e) {
		this.bXi = this.Xi;
		this.bYi = this.Yi;
		if (!this.hasMoved) {
			this.X = sX;
			this.Y = sY;
			this.setup.tap && this.setup.tap(this.evt);
		} else {
			this.setup.up && this.setup.up(this.evt);
		}
		this.isDraging = false;
		this.isDown = false;
		this.hasMoved = false;
		this.setup.up && this.setup.up(this.evt);
		if (this.elem.releaseCapture) this.elem.releaseCapture();
		this.evt = false;
	}
	this.pointerCancel = function(e) {
		if (this.elem.releaseCapture) this.elem.releaseCapture();
		this.isDraging = false;
		this.hasMoved = false;
		this.isDown = false;
		this.bXi = this.Xi;
		this.bYi = this.Yi;
		sX = 0;
		sY = 0;
	}
	if ('ontouchstart' in window) {
		this.elem.ontouchstart      = function (e) { self.pointerDown(e); return false;  }
		this.elem.ontouchmove       = function (e) { self.pointerMove(e); return false;  }
		this.elem.ontouchend        = function (e) { self.pointerUp(e); return false;    }
		this.elem.ontouchcancel     = function (e) { self.pointerCancel(e); return false;}
	}
	document.addEventListener("mousedown", function (e) {
		if (
			e.target === self.elem || 
			(e.target.parentNode && e.target.parentNode === self.elem) || 
			(e.target.parentNode.parentNode && e.target.parentNode.parentNode === self.elem)
		) {
			if (typeof e.stopPropagation != "undefined") {
				e.stopPropagation();
			} else {
				e.cancelBubble = true;
			}
			e.preventDefault();
			self.pointerDown(e); 
		}
	}, false);
	document.addEventListener("mousemove", function (e) { self.pointerMove(e); }, false);
	document.addEventListener("mouseup",   function (e) {
		self.pointerUp(e);
	}, false);
	document.addEventListener('gesturechange', function(e) {
		e.preventDefault();
		if (e.scale > 1) self.scale = 0.1; else if (e.scale  1) {
				if (e.preventDefault) e.preventDefault(); 
				self.scale = e.velocityExpansion;
				self.setup.scale && self.setup.scale(e);
			}
			return false;
		}, false);
	}
	if (window.addEventListener) this.elem.addEventListener('DOMMouseScroll', function(e) { 
		if (e.preventDefault) e.preventDefault(); 
		self.wheelDelta = e.detail * 10;
		self.setup.wheel && self.setup.wheel(e);
		return false; 
	}, false); 
	this.elem.onmousewheel = function () { 
		self.wheelDelta = -event.wheelDelta * .25;
		self.setup.wheel && self.setup.wheel(event);
		return false; 
	}
}

// ===== request animation frame =====
window.requestAnimFrame = (function(){
		return  window.requestAnimationFrame || 
		window.webkitRequestAnimationFrame   || 
		window.mozRequestAnimationFrame      || 
		window.oRequestAnimationFrame        || 
		window.msRequestAnimationFrame       || 
		function( run ){
			window.setTimeout(run, 16);
		};
})();

// ===== ge1doot global =====    js文件1
var ge1doot = ge1doot || {
	json: null,
	screen: null,
	pointer: null,
	camera: null,
	loadJS: function (url, callback, data) {
		if (typeof url == "string") url = [url];
		var load = function (src) {
			var script = document.createElement("script");
				if (callback) {
					if (script.readyState){
						script.onreadystatechange = function () {
							if (script.readyState == "loaded" || script.readyState == "complete"){
								script.onreadystatechange = null;
								if (--n === 0) callback(data || false);
							}
						}
					} else {
						script.onload = function() {
							if (--n === 0) callback(data || false);
						}
					}
				}
				script.src = src;
				document.getElementsByTagName("head")[0].appendChild(script);
		}
		for (var i = 0, n = url.length; i  11 || Math.abs(this.Y - sY) > 11) {
			this.hasMoved = true;
			if (this.isDown) {
				if (!this.isDraging) {
					this.startX = sX;
					this.startY = sY;
					this.setup.startDrag && this.setup.startDrag(e);
					this.isDraging = true;
				} else {
					this.setup.drag && this.setup.drag(e);
				}
			} else {
				sX = this.X;
				sY = this.Y;
			}
		}
		this.setup.move && this.setup.move(e);
	}
	this.pointerUp = function(e) {
		this.bXi = this.Xi;
		this.bYi = this.Yi;
		if (!this.hasMoved) {
			this.X = sX;
			this.Y = sY;
			this.setup.tap && this.setup.tap(this.evt);
		} else {
			this.setup.up && this.setup.up(this.evt);
		}
		this.isDraging = false;
		this.isDown = false;
		this.hasMoved = false;
		this.setup.up && this.setup.up(this.evt);
		if (this.elem.releaseCapture) this.elem.releaseCapture();
		this.evt = false;
	}
	this.pointerCancel = function(e) {
		if (this.elem.releaseCapture) this.elem.releaseCapture();
		this.isDraging = false;
		this.hasMoved = false;
		this.isDown = false;
		this.bXi = this.Xi;
		this.bYi = this.Yi;
		sX = 0;
		sY = 0;
	}
	if ('ontouchstart' in window) {
		this.elem.ontouchstart      = function (e) { self.pointerDown(e); return false;  }
		this.elem.ontouchmove       = function (e) { self.pointerMove(e); return false;  }
		this.elem.ontouchend        = function (e) { self.pointerUp(e); return false;    }
		this.elem.ontouchcancel     = function (e) { self.pointerCancel(e); return false;}
	}
	document.addEventListener("mousedown", function (e) {
		if (
			e.target === self.elem || 
			(e.target.parentNode && e.target.parentNode === self.elem) || 
			(e.target.parentNode.parentNode && e.target.parentNode.parentNode === self.elem)
		) {
			if (typeof e.stopPropagation != "undefined") {
				e.stopPropagation();
			} else {
				e.cancelBubble = true;
			}
			e.preventDefault();
			self.pointerDown(e); 
		}
	}, false);
	document.addEventListener("mousemove", function (e) { self.pointerMove(e); }, false);
	document.addEventListener("mouseup",   function (e) {
		self.pointerUp(e);
	}, false);
	document.addEventListener('gesturechange', function(e) {
		e.preventDefault();
		if (e.scale > 1) self.scale = 0.1; else if (e.scale  1) {
				if (e.preventDefault) e.preventDefault(); 
				self.scale = e.velocityExpansion;
				self.setup.scale && self.setup.scale(e);
			}
			return false;
		}, false);
	}
	if (window.addEventListener) this.elem.addEventListener('DOMMouseScroll', function(e) { 
		if (e.preventDefault) e.preventDefault(); 
		self.wheelDelta = e.detail * 10;
		self.setup.wheel && self.setup.wheel(e);
		return false; 
	}, false); 
	this.elem.onmousewheel = function () { 
		self.wheelDelta = -event.wheelDelta * .25;
		self.setup.wheel && self.setup.wheel(event);
		return false; 
	}
}

// ===== request animation frame =====
window.requestAnimFrame = (function(){
		return  window.requestAnimationFrame || 
		window.webkitRequestAnimationFrame   || 
		window.mozRequestAnimationFrame      || 
		window.oRequestAnimationFrame        || 
		window.msRequestAnimationFrame       || 
		function( run ){
			window.setTimeout(run, 16);
		};
})();

到此这篇关于HTML+CSS+JavaScript实现图片3D展览的示例代码的文章就介绍到这了,更多相关HTML图片3D展览内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章,希望大家以后多多支持IT俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/navsub/html5/13762.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部