云cloud

云cloud


更多有趣示例 尽在 小红砖社区

示例

在这里插入图片描述

HTML

<!--
Visit this project on GitHub at https://github.com/enesser/low-poly-clouds-webgl
-->

CSS

body {
    background-color: #000;
    color: #fff;
    font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
    margin: 0;
    overflow: hidden;
    padding: 0px;
    position: relative;
}

a {
  color: #00b7ff;
}

JS

'use strict';

/* global dat: true */

var LowPolyCloudWebGLDemo = LowPolyCloudWebGLDemo || {};

/**
 * Create an instance of configurable settings for the demo.
 * You can allow or disallow a GUI for these settings with the query string "ui=true/false", ie: http://localhost:3000?ui=false
 * @return {object} Scene settings
 */
LowPolyCloudWebGLDemo.settings = function() {

    /**
     * Default sun color
     * @type {String}
     */
    const sunColor = '#fcd2a8',

        /**
         * Default sun intensity
         * @type {Number}
         */
        sunIntensity = 0.53,

        /**
         * Default ambient light color
         * @type {String}
         */
        ambientLight = '#8c8c8c',

        /**
         * Default sky color
         * @type {String}
         */
        skyColor = '#67b4e7',

        /**
         * Default show wireframe state for sky
         * @type {Boolean}
         */
        skyWireframe = false,

        /**
         * Default cloud color
         * @type {String}
         */
        cloudsColor = '#ffffff',

        /**
         * Default cloud opacity
         * @type {Number}
         */
        cloudsOpacity = 0.79,

        /**
         * Default show wireframe state for clouds
         * @type {Boolean}
         */
        cloudsWireframe = false,

        /**
         * Default cloud base velocity
         * @type {Number}
         */
        cloudsBaseVelocity = 0.008,

        /**
         * Project URL
         * @type {String}
         */
        homepage = 'https://github.com/enesser/low-poly-clouds-webgl';

    let gui = new dat.GUI({
        width: 360
    });
    gui.close();

    /**
     * Settings schema business object
     * @type {Object}
     */
    let settingsSchema = {
        /**
         * Reset settings to default
         */
        reset: function() {
            this.sunColor = sunColor;
            this.sunIntensity = sunIntensity;
            this.ambientLight = ambientLight;
            this.skyColor = skyColor;
            this.skyWireframe = skyWireframe;
            this.cloudsColor = cloudsColor;
            this.cloudsOpacity = cloudsOpacity;
            this.cloudsWireframe = cloudsWireframe;
            this.cloudsBaseVelocity = cloudsBaseVelocity;

            for (let folder in gui.__folders) {
                for (let i in gui.__folders[folder].__controllers) {
                    gui.__folders[folder].__controllers[i].updateDisplay();
                }
            }
        },

        /**
         * Go to home page
         */
        homepage: function() {
            window.open(homepage, '_blank');
        }
    };

    /**
     * Bind settings schema object to dat.gui interface.
     * @param  {object} settingsSchema
     */
    function bindSettingsSchemaToUi(settingsSchema) {

        let sunFolder = gui.addFolder('Sun');
        sunFolder.addColor(settingsSchema, 'sunColor');
        sunFolder.add(settingsSchema, 'sunIntensity').min(-10).max(50);
        sunFolder.addColor(settingsSchema, 'ambientLight');

        let skyFolder = gui.addFolder('Sky');
        skyFolder.addColor(settingsSchema, 'skyColor');
        skyFolder.add(settingsSchema, 'skyWireframe');

        let cloudsFolder = gui.addFolder('Clouds');
        cloudsFolder.addColor(settingsSchema, 'cloudsColor');
        cloudsFolder.add(settingsSchema, 'cloudsOpacity').min(0).max(1);
        cloudsFolder.add(settingsSchema, 'cloudsWireframe');
        cloudsFolder.add(settingsSchema, 'cloudsBaseVelocity').min(0).max(3);

        gui.add(settingsSchema, 'reset');
        gui.add(settingsSchema, 'homepage');
    }

    settingsSchema.reset();
    bindSettingsSchemaToUi(settingsSchema);
    return settingsSchema;
};

/* global console, THREE: true */

/**
 * Create an instance of world, represents the ThreeJS model with meshes and materials.
 * You can load high or low quality textures with the query string "quality=high/low", ie: http://localhost:3000?quality=low
 * @return {object} world model
 */
LowPolyCloudWebGLDemo.world = function() {

    const pathWorldModel = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/168282/low-poly-clouds.obj';
    const pathWorldMaterial = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/168282/low-poly-clouds.mtl';

    /**
     * Represents the ThreeJS model of world with meshes and materials.
     * @type {Object}
     */
    let worldObject = {

        /**
         * Are textures and materials loaded yet?
         * @type {Boolean}
         */
        isLoaded: false,

        /**
         * Texture and materials loading progress
         * @type {Number}
         */
        percentLoaded: 0,

        /**
         * Sky background mesh
         * @type {[type]}
         */
        background: null,

        /**
         * Sky background material
         * @type {[type]}
         */
        backgroundMaterial: null,

        /**
         * Cloud material
         * @type {[type]}
         */
        cloudsMaterial: null,

        /**
         * Cloud meshes
         * @type {Array}
         */
        clouds: []
    };

    /**
     * Load materials and textures, then map them to the object.
     * @param  {object} worldObject Target object to map.
     */
    function mapMaterialsTexturesToObject(worldObject) {

        let loader = new THREE.OBJMTLLoader();
        loader.load(pathWorldModel, pathWorldMaterial, (o) => {

                const cloudBaseSize = 1.8;

                worldObject.clouds = [];
                worldObject.background = o.children.find(child => child.name === 'Plane_Plane.003');
                worldObject.background.receiveShadow = true;
                worldObject.backgroundMaterial = worldObject.background.children[1].material;
                worldObject.backgroundMaterial.depthWrite = false;
                worldObject.backgroundMaterial.receiveShadow = true;

                for (let cloudTemplate of[
                    o.children.find(child => child.name === 'Cloud2_Icosphere.011'),
                    o.children.find(child => child.name === 'Cloud1_Icosphere.005')
                ]) {

                    worldObject.cloudsMaterial = cloudTemplate.children[1].material;
                    cloudTemplate.position.setY(cloudTemplate.position.y - 10);

                    for (let i = 0; i < 8; i++) {

                        let cloud = cloudTemplate.clone();

                        //randomly size clouds
                        let cloudSize = cloudBaseSize + (Math.random() * 1.2);
                        cloud.scale.set(cloudSize, cloudSize, cloudSize);

                        //randomly place clouds
                        let posXFlip = (Math.floor(Math.random() * 2) + 1) % 2 === 0 ? 1 : -1;
                        let posYFlip = (Math.floor(Math.random() * 2) + 1) % 2 === 0 ? 1 : -1;
                        let posX = cloud.position.x + (Math.random() * 50);
                        let posY = posYFlip > 0 ? cloud.position.y + (Math.random() * 3) : cloud.position.y - (Math.random() * 3);
                        cloud.position.setX(posX * posXFlip);
                        cloud.position.setY(posY);
                        cloud.position.setZ(cloud.position.z + (Math.random() * 3));

                        //give cloud random velocity accelerator
                        cloud.velocityAccelerator = (Math.random() * 0.008);

                        //add cloud to the array
                        worldObject.clouds.push(cloud);
                    }
                }

                worldObject.cloudsMaterial.transparent = true;
                worldObject.cloudsMaterial.depthWrite = false;

                worldObject.isLoaded = true;
            },

            /**
             * Successful load
             * @param  {object} xhr XmlHttpRequest
             */
            (xhr) => {
                if (xhr.lengthComputable) {
                    worldObject.percentLoaded = xhr.loaded / xhr.total * 100;
                }
            },

            /**
             * Error loading world materials and textures
             * @param  {object} xhr XmlHttpRequest
             */
            (xhr) => {
                console.error('Error loading world materials and textures', xhr);
            });
    }

    mapMaterialsTexturesToObject(worldObject);
    return worldObject;
};

/* global window, THREE: true */

/**
 * Entry point for Low Poly Cloud WebGL Demo
 * @param  {object} window
 */
((window, document) => {
    window.onload = () => {

        let scene,
            camera,
            renderer,
            directionalLightColor,
            directionalLight,
            ambientLightColor,
            ambientLight,
            settings,
            world,
            windowHalfX = window.innerWidth / 2,
            windowHalfY = window.innerHeight / 2;

        /**
         * Initialize scene
         */
        (function init() {

            //setup scene and perspective camera with a fov of 45, a near plane at 1, and a far plane at 1000
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
            camera.position.set(0, 4, 64);
            camera.lookAt(scene.position);

            //setup renderer with antialiasing enabled
            renderer = new THREE.WebGLRenderer({
                antialias: true
            });
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.setSize(window.innerWidth, window.innerHeight);

            //add rendering div to the DOM
            let container = document.createElement('div');
            document.body.appendChild(container);
            container.appendChild(renderer.domElement);

            //create the sun
            directionalLightColor = new THREE.Color();
            directionalLight = new THREE.DirectionalLight(directionalLightColor);
            directionalLight.position.set(-20, 9.7, 14);

            scene.add(directionalLight);

            //create ambient lighting
            ambientLightColor = new THREE.Color();
            ambientLight = new THREE.AmbientLight(ambientLightColor);
            scene.add(ambientLight);

            //import settings
            settings = LowPolyCloudWebGLDemo.settings();

            //import the world, but don't add it to the scene until the model is finished loading
            world = LowPolyCloudWebGLDemo.world();
            world.isAddedToScene = false;


            //update renderer and camera aspect to the new size of the drawing area on window resize
            window.addEventListener('resize', () => {
                windowHalfX = window.innerWidth / 2;
                windowHalfY = window.innerHeight / 2;
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);

            }, false);
        })();

        /**
         * Render method, called each time a frame is rendered
         */
        (function render() {

            //update sun with settings
            directionalLight.intensity = settings.sunIntensity;
            directionalLightColor.setStyle(settings.sunColor);
            directionalLight.color = directionalLightColor;

            //update ambient lighting with settings
            ambientLightColor.setStyle(settings.ambientLight);
            ambientLight.color = ambientLightColor;

            //when world model is fully loaded (including materials and textures)
            if (world.isLoaded) {

                //add the world to the scene only when it's fully loaded
                if (!world.isAddedToScene) {

                    scene.add(world.background);

                    for (let cloud of world.clouds) {
                        scene.add(cloud);
                    }

                    world.isAddedToScene = true;
                }

                //adjust sky
                world.backgroundMaterial.color.setStyle(settings.skyColor);
                world.backgroundMaterial.wireframe = settings.skyWireframe;

                //adjust clouds
                world.cloudsMaterial.color.setStyle(settings.cloudsColor);
                world.cloudsMaterial.opacity = settings.cloudsOpacity;
                world.cloudsMaterial.wireframe = settings.cloudsWireframe;

                //move clouds
                for (let cloud of world.clouds) {
                    let newX = cloud.position.x + (settings.cloudsBaseVelocity + cloud.velocityAccelerator);
                    if (newX > 60) {
                        newX = -60;
                    }
                    cloud.position.setX(newX);
                }
            }

            //render the scene and loop for next frame update
            renderer.render(scene, camera);

            requestAnimationFrame(render);
        })();
    };
})(window, document);

猜你喜欢

转载自blog.csdn.net/weixin_45544796/article/details/107225512