上一篇博文展示了卡片中的VR展示,那篇主要是卡片的3D转动来展示未显示的部分图片。这篇,我们来点科幻的。
我们在卡片中播放视频的同时来拖动卡片或转动它。像下面那样:
这个主要依赖了两个库,具体代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 3D场景库引入-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.148.0/three.min.js"></script>
<!--动画效果库引入-->
<script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
background: #1e2024;
}
button {
width: 100px;
height: 100px;
border-radius: 50%;
background-color: #95a8a6;
border: 5px solid #0f1515;
position: absolute;
left: 50%;
top: 50%;
cursor: pointer;
transform: translate(-50%, -50%) scale(1);
transition: transform 0.35s ease;
transform-origin: 50% 50%;
}
button:before {
position: absolute;
content: "";
width: 0px;
height: 0px;
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-left: 30px solid #0f1515;
left: 50%;
top: 50%;
transform: translate(-30%, -50%);
}
button:hover {
transform: translate(-50%, -50%) scale(1.1);
}
.lady {
position: absolute;
margin: auto;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 525px;
opacity: 0.4;
}
canvas {
opacity: 0;
}
</style>
</head>
<body>
<!--首先图片是要有的,这个是视频中截取的开头图片你也可以换成别的,博文中我没有上传这个-->
<img class="lady" src="img.png" >
</body>
<script>
//创建一个Three.js场景对象,并设置了背景颜色为黑色。
var scene = new THREE.Scene();
scene.background = new THREE.Color( 0x1e2024);
//创建一个透视摄像机对象
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
//创建一个Three.js渲染器对象
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//创建了一个平面几何体对象
var planeGeometry = new THREE.PlaneGeometry(9.45, 6.3);
//创建一个视频元素
var video = document.createElement('video');
var videoTexture = new THREE.VideoTexture(video);
//视频在这里
video.src ="http://vjs.zencdn.net/v/oceans.mp4";
video.crossOrigin = "anonymous";
video.muted = 'muted';
video.preload = "auto";
//搞一个着色器材质,从video创建一个视频纹理
var material = new THREE.ShaderMaterial({
uniforms: {
u_lightPos: {value: new THREE.Vector3(0, 0, 10)},
u_texture: {value: videoTexture}
},
vertexShader: `
varying vec3
v_normal;
varying vec3 v_position;
varying vec2 v_uv;
void main() {
v_normal = normalMatrix * normal;
v_position = vec3(modelMatrix * vec4(position, 1.0));
v_uv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`,
fragmentShader: `
uniform sampler2D u_texture;
varying vec2 v_uv;
varying vec3 v_normal;
varying vec3 v_position;
uniform vec3 u_lightPos;
void main() {
vec3 normal = normalize(v_normal);
vec3 lightDir = normalize(u_lightPos - v_position);
float diffuse = max(dot(lightDir, normal), 0.0);
gl_FragColor = texture2D(u_texture, v_uv) * diffuse;
}
`
});
var plane = new THREE.Mesh(planeGeometry, material);
scene.add(plane);
var pointLight = new THREE.PointLight(0xff0000, 1, 100);
pointLight.position.set(0, 0, 60);
scene.add(pointLight);
camera.position.z = 7;
var playButton = document.createElement("button");
document.body.appendChild(playButton);
var tl = new gsap.timeline();
function playVideo(){
video.play();
if (navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1) {
video.muted = 'muted';
} else {
video.muted = false;
}
}
//搞一个按钮
playButton.addEventListener("click", function() {
tl.set('body',{background:'transparent'});
tl.to('button',1,{opacity:0});
tl.to('.lady',1,{opacity:0},"-0.5");
tl.to('canvas',1,{opacity:1},"-0.5");
tl.call(playVideo);
});
video.addEventListener("ended", function() {
video.currentTime = 0;
video.pause();
video.muted = 'muted';
tl.set('body',{background:'#1e2024'});
tl.to('canvas',1,{opacity:0});
tl.to('.lady',1,{opacity:1},"-0.5");
tl.to('button',1,{opacity:1});
});
//添加一个监听事件
document.addEventListener("mousemove", onMouseMove);
//鼠标事件
function onMouseMove(event) {
var x = (event.clientX / window.innerWidth) * 2 - 1;
var y = -(event.clientY / window.innerHeight) * 2 + 1;
plane.position.x = x;
plane.position.y = y;
plane.position.z = x * y;
plane.rotation.x = x * 0.2;
plane.rotation.y = y * 0.2;
}
window.onresize = function() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
//场景渲染
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
render();
</script>
</html>