claygl/example/cubeanim.html

227 lines
7.7 KiB
HTML

<html>
<head>
<meta charset="utf-8">
<script src="../dist/claygl.js"></script>
<style>
body{
background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
}
#cubeColor {
width: 100px;
height: 100px;
position: absolute;
bottom: 10px;
right: 10px;
}
#shape {
position: absolute;
left:0px;
bottom: 0px;
}
</style>
</head>
<body style="margin:0px;">
<canvas width="1200" height="640" id="main"></canvas>
<div id="cubeColor" style="background-color: rgb(245, 50, 50);"></div>
<div id="fps" style="position:absolute;left:10px;top:10px;color:white;"></div>
<script>
//----------------------------------
// Prepare animation shape data
//----------------------------------
var canvas = document.createElement('canvas');
canvas.id = 'shape';
var SIZE = 50;
canvas.width = SIZE;
canvas.height = SIZE;
var ctx = canvas.getContext('2d');
function drawCross() {
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, SIZE, SIZE);
ctx.save()
ctx.scale(0.6, 0.6);
ctx.translate(10, 10);
ctx.strokeStyle = 'white';
ctx.beginPath();
ctx.lineWidth = SIZE / 3.5;
ctx.moveTo(0, 0);
ctx.lineTo(SIZE, SIZE);
ctx.stroke();
ctx.moveTo(SIZE, 0);
ctx.lineTo(0, SIZE);
ctx.stroke();
ctx.restore();
return ctx.getImageData(0, 0, SIZE, SIZE).data;
}
function drawCheck() {
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, SIZE, SIZE);
ctx.scale(0.7, 0.7);
ctx.translate(10, 10);
ctx.strokeStyle = 'white';
ctx.beginPath();
ctx.lineWidth = SIZE / 3.5;
ctx.moveTo(0, SIZE / 2);
ctx.lineTo(SIZE / 2, SIZE / 1.2);
ctx.lineTo(SIZE, SIZE / 10);
ctx.stroke();
return ctx.getImageData(0, 0, SIZE, SIZE).data;
}
document.body.appendChild(canvas);
function pixelToPositionArray(pixels) {
var position = [];
for (var i = 0; i < pixels.length; i+=4) {
var r = pixels[i];
if (r < 128) {
continue;
}
var idx = i / 4;
var x = (idx % SIZE) / SIZE * 40 - 20;
var y = 20 - (idx / SIZE) / SIZE * 40;
var z = Math.random() * 6;
position.push([x, y, z]);
}
return position;
}
var crossPixels = drawCross();
var checkPixels = drawCheck();
var crossPosArr = pixelToPositionArray(crossPixels);
var checkPosArr = pixelToPositionArray(checkPixels);
var larger = checkPosArr.length < crossPosArr.length ? crossPosArr: checkPosArr;
var smaller = larger == crossPosArr ? checkPosArr: crossPosArr;
for (var i = smaller.length; i < larger.length; i++) {
var random = smaller[Math.round(Math.random() * (smaller.length - 1))];
random = random.slice();
random[2] += Math.random() * 3;
smaller[i] = random;
}
var positionArr = [];
for (var i = 0; i < crossPosArr.length; i++) {
positionArr[i] = crossPosArr[i].slice();
}
//----------------------------------
// Prepare scene
//----------------------------------
var Shader = clay.Shader;
var renderer = new clay.Renderer({
canvas: document.getElementById('main')
});
var shadowMapPass = new clay.prePass.ShadowMap({
// softShadow: clay.prePass.VSM
});
renderer.resize(window.innerWidth, window.innerHeight);
var scene = new clay.Scene();
var camera = new clay.camera.Perspective({
aspect: renderer.getViewportAspect()
});
camera.position.set(0, 0, 40);
var shader = clay.shader.library.get('clay.standard');
var cubeMat = new clay.Material({
shader: shader
});
var root = new clay.Node();
scene.add(root);
var cubeList = [];
var gltfLoader = new clay.loader.GLTF();
var cubeGeo = new clay.geometry.Cube();
for (var i = 0; i < positionArr.length; i++) {
var position = positionArr[i];
var mesh = new clay.Mesh({
material: cubeMat,
geometry: cubeGeo
});
mesh.position.set(position[0], position[1], position[2]);
mesh.rotation.rotateX(Math.random() * Math.PI * 2);
mesh.rotation.rotateZ(Math.random() * Math.PI * 2);
mesh.scale.set(0.5, 0.5, 0.5);
root.add(mesh);
cubeList.push(mesh);
}
var light = new clay.light.Directional({
shadowResolution: 1024,
shadowBias: 0.005,
intensity: 0.7
});
light.position.set(0, 30, 30);
light.lookAt(scene.position);
scene.add(light);
scene.add(new clay.light.Ambient({
intensity: 0.3
}));
var timeline = new clay.Timeline();
timeline.start();
timeline.on('frame', function(deltaTime) {
var start = new Date().getTime();
shadowMapPass.render(renderer, scene, camera);
var drawInfo = renderer.render(scene, camera);
var renderTime = new Date().getTime() - start;
document.getElementById('fps').innerHTML =
Math.round(1000 / deltaTime) + '<br />'
+ renderTime + '<br />';
var color = document.getElementById('cubeColor').style.backgroundColor;
color = color.match(/rgb\((.*?)\)/)[1].split(/\s*,\s*/).map(function(item) {
return parseInt(item) / 255;
});
for (var i = 0; i < cubeList.length; i++) {
cubeList[i].material.set('color', color);
var pos = positionArr[i];
clay.Quaternion.rotateY(cubeList[i].rotation, cubeList[i].rotation, deltaTime / 500);
clay.Vector3.set(cubeList[i].position, pos[0], pos[1], pos[2]);
}
});
document.body.addEventListener('mousemove', function(e) {
var dx = e.pageX - window.innerWidth / 2;
root.rotation.identity().rotateY(dx / 1000);
});
var obj = {
position: positionArr
}
var current = crossPosArr;
setInterval(function() {
var another = current == crossPosArr ? checkPosArr: crossPosArr;
timeline.animate(obj)
.when(1000, {
position: another
}).start("CubicInOut");
current = another;
}, 4000);
</script>
</body>
</html>