海底世界鱼群效果

代码语言: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