three+gsap实现旋转扭曲的三维金字塔动画效果代码

代码语言:html

所属分类:动画

代码描述:three+gsap实现旋转扭曲的三维金字塔动画效果代码

代码标签: 扭曲 三维 金字塔 动画 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  

  
  
  
  
<style>
* {
  margin: 0;
  padding: 0;
}

html, body {
  overflow: hidden;
}

.webgl {
  position: fixed;
  top: 0;
  left: 0;
  outline: none;
  cursor: pointer;
}
</style>




</head>

<body>
  <canvas class="webgl"></canvas>

<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.5.2.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/CustomEase3.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.126.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/OrbitControls.126.js"></script>

      <script >


// Some settings to use
const settings = {
  pyramidHeight: 3,

  // Changing numSides "breaks" when changing to anything else
  // TODO? Make able to be dynamic
  numSides: 4,

  rows: 3,
  sideLength: 1 };


// TODO? Add GUI for controlling geometry and colors

const colors = {
  c1: {
    start: new THREE.Color("blue"),
    end: new THREE.Color("blue") },

  c2: {
    start: new THREE.Color("blue"),
    end: new THREE.Color("red") } };




// Helper function
const mapRange = function (in_min, in_max, out_min, out_max, num) {
  return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
};


// The GSAP custom ease is nicer
gsap.registerPlugin(CustomEase);
const rotationEase = CustomEase.create("rotEase", "M0,0,C0,0,0.1,0.9,0.4,1,0.6,1,1,0,1,0");

// Super rough approximation of the above
// const rotationEase = (progress) => progress < 0.5 ? progress * 2 : 1 - (progress * 2 - 1);





// The textures to use for the pyramid
const textureLoader = new THREE.TextureLoader();
// From https://3dtextures.me/2018/04/19/gun-metal-scratched-001/
const pyramidColor = textureLoader.load("//repo.bfw.wiki/bfwrepo/image/5df5d982ef313.png");
const pyramidOCC = textureLoader.load("//repo.bfw.wiki/bfwrepo/image/60ca852351758.png");
const pyramidMetal = textureLoader.load("//repo.bfw.wiki/bfwrepo/image/6033443fea87a.png");
const pyramidRough = textureLoader.load("//repo.bfw.wiki/bfwrepo/image/5ef16a3f39164.png");
pyramidColor.wrapS = pyramidColor.wrapT = THREE.RepeatWrapping;
pyramidColor.repeat.set(4, 4);


// Set things up
const canvas = document.querySelector("canvas.webgl");
const scene = new THREE.Scene();

// const axesHelper = new THREE.AxesHelper(5);
// scene.add(axesHelper);

const halfSideLength = settings.sideLength / 2;
const triangleHeight = settings.pyramidHeight / settings.rows;
const points = [];
const uvs = [];

// Rotate face about y axis according to given angle
const yAxis = new THREE.Vector3(0, 1, 0);
function getPoint(angle, x, y, z) {
  const uvX = mapX(x);
  const uvY = y / settings.pyramidHeight;
  uvs.push(uvX);
  uvs.push(uvY);

  return new THREE.Vector3(x, y, z).applyAxisAngle(yAxis, angle);
}

const xBound = settings.rows * halfSideLength;
const mapX = num => mapRange(-xBound, xBound, 0, 1, num);

// Create all triangles, starting with bottom row on left going right then up
for (let side = 0; side < settings.numSides; side++) {
  const sideRotAngle = 2 * Math.PI / settings.numSides * side;

  for (let rowFromBot = settings.rows; rowFromBot > 0; rowFromBot--) {
    const numTrianglesInRow = 1 + 2 * (rowFromBot - 1);

    const rowStartX = -rowFromBot * halfSideLength;
    const startY = (settings.rows - rowFromBot) * triangleHeight;
    const endY = startY + triangleHeight;
    const startZ = rowFromBot * halfSideLength;

    for (let triangleInRow = 0; triangleInRow < numTrianglesInRow; triangleInRow++) {
      // Create points of triangle
      let point1, point2, point3;
      const pointStartX = rowStartX + triangleInRow * halfSideLength;

      if (triangleInRow % 2 === 0) {
        point1 = getPoint(sideRotAngle, pointStartX, startY, startZ);
        point2 = getPoint(sideRotAngle, pointStartX + halfSideLength, endY, startZ - halfSideLength);
        point3 = getPoint(sideRotAngle, pointStartX + settings.sideLength, startY, startZ);
      } else {
        point1 = getPoint(sideRotAngle, pointStartX, endY, startZ - halfSideLength);
        point2 = getPoint(sideRotAngle, pointStartX + halfSideL.........完整代码请登录后点击上方下载按钮下载查看

网友评论0