海底世界鱼群效果
代码语言:html
所属分类:动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> body { width: 100vw; height: 100vh; background-color: black; overflow: hidden; margin: 0; padding: 0; background:url(http://repo.bfw.wiki/bfwrepo/image/5e4c71cd307e7.png);/*https://www.wuwm.com/post/poem-underwater-unsettlement#stream/0 */ background-size:cover; background-repeat:no-repeat; } #tank { width:100%; height:100%; } .school { position:absolute; top:50%; left:50%; } .fish { will-change:left,top; position:absolute; } </style> </head> <body translate="no"> <p id="controls"></p> <div id="tank"></div> <script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/dat.gui-min.js"></script> <script > var myoptions, gui; var fishes = ["🐟", "🐠", "🐡"] var tank = document.getElementById("tank") var WINDOW_MIN; var MIN_THRESHOLD = 640 window.onload = ()=>{ generateControls() initializeTank() } window.addEventListener("resize", () => { initializeTank() }) /*Fish functions*/ function initializeTank() { WINDOW_MIN = Math.min(tank.clientHeight, tank.clientWidth) generateFishTank() if(WINDOW_MIN<=MIN_THRESHOLD) { gui.close() } else { gui.open() } } function generateFishTank() { tank.innerHTML = "" for (let i = 0; i < myoptions.NumFishGroups; i++) { let numFish = 1 if (!myoptions.SingleFishOnly && (Math.random() * 100) > (100 - myoptions.PercentSchools)) { numFish = getRandomInt(1, myoptions.MaxPerSchool) } let hueShift = myoptions.ColorChanging ? getRandomInt(0, 360) : 0 let school = generateSchool(numFish, pick(fishes), hueShift) tank.appendChild(school) loop(school) } } function generateSchool(numFish, icon, hueShift) { let maxFishSize = WINDOW_MIN < MIN_THRESHOLD ? 50 : 100 let root = document.createElement("div"); root.setAttribute("class", "school") root.style.width = `${getRandomFloat(100,1000)}px` root.style.height = `${getRandomFloat(100,700)}px` root.style.left = `${getRandomFloat(0,100)}%` root.style.top = `${getRandomFloat(0,100)}%` for (let i = 0; i < numFish; i++) { let fishPos = [getRandomFloat(0, 100), getRandomFloat(0, 100)] let size = getRandomInt(10, maxFishSize) let fish = generateFish(fishPos, hueShift, size, icon) root.appendChild(fish); } return root } function loop(school) { var timeout = school.getAttribute('data-timeout') clearTimeout(timeout) let minInterval = myoptions.SwimSpeed == "Slow" ? 10000 : myoptions.SwimSpeed == "Moderate" ? 5000 : 3000 let maxInterval = myoptions.SwimSpeed == "Slow" ? 30000 : myoptions.SwimSpeed == "Moderate" ? 20000 : 10000 let nextCall = getRandomInt(minInterval, maxInterval) moveSchool(school, nextCall) timeout = setTimeout(loop.bind(this, school), nextCall) school.setAttribute('data-timeout', timeout) } function moveSchool(school, nextCall) { var currentX = parseInt(school.getAttribute("data-x")) || 0 var newX = getRandomFloat(-tank.clientWidth, tank.clientWidth) var newY = getRandomFloat(-tank.clientHeight / 4, tank.clientHeight / 4) var isRight = newX > currentX; [...school.querySelectorAll(".fish")].forEach(fish => { let direction = fish.querySelector(".direction") direction.style.transform = `rotateY(${isRight?180:0}deg)` direction.style.transition = `transform ${getRandomFloat(.1,1)}s` if (school.children.length > 1) { let currentLeft = parseInt(fish.style.left.replace(/%/, "")) let currentTop = parseInt(fish.style.top.replace(/%/, "")) let newLeft = `${currentLeft + getRandomFloat(-20,20)}%` let newTop = `${currentTop + getRandomFloat(-20,20)}%` fish.style.left = newLeft fish.style.top = newTop let easing = Math.random() > .5 ? "ease" : "ease-in-out" fish.style.transition = `all ${nextCall}ms ${easing}` } .........完整代码请登录后点击上方下载按钮下载查看
网友评论0