JavaScript特效代码收集

页面“线条”效果

引自:http://www.sojson.com/blog/127.html

<!-- 这个script 引入得放到<body> 里,放到header 里,会报错。并且不依赖其他js 插件。 --!>
<!-- 参数解释 count  :线条数量;zindex :层级;opacity:透明度;color   :线条颜色,最好用RGB颜色 --!>
<script count="200" zindex="-2" opacity="0.5" color="47,135,193" type="text/javascript"> 
! function() {
	//封装方法,压缩之后减少文件大小
	function get_attribute(node, attr, default_value) {
		return node.getAttribute(attr) || default_value;
	}
	//封装方法,压缩之后减少文件大小
	function get_by_tagname(name) {
		return document.getElementsByTagName(name);
	}
	//获取配置参数
	function get_config_option() {
		var scripts = get_by_tagname("script"),
			script_len = scripts.length,
			script = scripts[script_len - 1]; //当前加载的script
		return {
			l: script_len, //长度,用于生成id用
			z: get_attribute(script, "zIndex", -1), //z-index
			o: get_attribute(script, "opacity", 0.5), //opacity
			c: get_attribute(script, "color", "0,0,0"), //color
			n: get_attribute(script, "count", 99) //count
		};
	}
	//设置canvas的高宽
	function set_canvas_size() {
		canvas_width = the_canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, 
		canvas_height = the_canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
	}

	//绘制过程
	function draw_canvas() {
		context.clearRect(0, 0, canvas_width, canvas_height);
		//随机的线条和当前位置联合数组
		var all_array = [current_point].concat(random_lines);
		var e, i, d, x_dist, y_dist, dist; //临时节点
		//遍历处理每一个点
		random_lines.forEach(function(r) {
			r.x += r.xa, 
			r.y += r.ya, //移动
			r.xa *= r.x > canvas_width || r.x < 0 ? -1 : 1, 
			r.ya *= r.y > canvas_height || r.y < 0 ? -1 : 1, //碰到边界,反向反弹
			context.fillRect(r.x - 0.5, r.y - 0.5, 1, 1); //绘制一个宽高为1的点
			for (i = 0; i < all_array.length; i++) {
				e = all_array[i];
				//不是当前点
				if (r !== e && null !== e.x && null !== e.y) {
						x_dist = r.x - e.x, //x轴距离 l
						y_dist = r.y - e.y, //y轴距离 n
						dist = x_dist * x_dist + y_dist * y_dist; //总距离, m
					dist < e.max && (e === current_point && dist >= e.max / 2 && (r.x -= 0.03 * x_dist, r.y -= 0.03 * y_dist), //靠近的时候加速
						d = (e.max - dist) / e.max, 
						context.beginPath(), 
						context.lineWidth = d / 2, 
						context.strokeStyle = "rgba(" + config.c + "," + (d + 0.2) + ")", 
						context.moveTo(r.x, r.y), 
						context.lineTo(e.x, e.y), 
						context.stroke());
				}
			}
			all_array.splice(all_array.indexOf(r), 1);

		}), frame_func(draw_canvas);
	}
	//创建画布,并添加到body中
	var the_canvas = document.createElement("canvas"), //画布
		config = get_config_option(), //配置
		canvas_id = "c_n" + config.l, //canvas id
		context = the_canvas.getContext("2d"), canvas_width, canvas_height, 
		frame_func = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(func) {
			window.setTimeout(func, 1000 / 45);
		}, random = Math.random, 
		current_point = {
			x: null, //当前鼠标x
			y: null, //当前鼠标y
			max: 20000
		};
	the_canvas.id = canvas_id;
	the_canvas.style.cssText = "position:fixed;top:0;left:0;z-index:" + config.z + ";opacity:" + config.o;
	get_by_tagname("body")[0].appendChild(the_canvas);
	//初始化画布大小

	set_canvas_size(), window.onresize = set_canvas_size;
	//当时鼠标位置存储,离开的时候,释放当前位置信息
	window.onmousemove = function(e) {
		e = e || window.event, current_point.x = e.clientX, current_point.y = e.clientY;
	}, window.onmouseout = function() {
		current_point.x = null, current_point.y = null;
	};
	//随机生成config.n条线位置信息
	for (var random_lines = [], i = 0; config.n > i; i++) {
		var x = random() * canvas_width, //随机位置
			y = random() * canvas_height,
			xa = 2 * random() - 1, //随机运动方向
			ya = 2 * random() - 1;
		random_lines.push({
			x: x,
			y: y,
			xa: xa,
			ya: ya,
			max: 6000 //沾附距离
		});
	}
	//0.1秒后绘制
	setTimeout(function() {
		draw_canvas();
	}, 100);
}();
</script>

效果预览:https://cnfaq.cn/tryjs/linesbg.html

倒计时

居中显示到今年年底的倒计时秒数,以汉字表示。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
            <title>
                Welcome
            </title>
            <style>
                html,body {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        body {
            display: flex;
            align-items: center; /*定义body的元素垂直居中*/
            justify-content: center; /*定义body的里的元素水平居中*/
        }
            </style>
        </meta>
    </head>
    <body>
        <h1 id="show">
        </h1>
        <script>
            //将数字(整数)转为汉字,从零到一亿亿,需要小数的可自行截取小数点后面的数字直接替换对应arr1的读法就行了
function convertToChinaNum(num) {
    var arr1 = new Array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
    var arr2 = new Array('', '十', '百', '千', '万', '十', '百', '千', '亿', '十', '百', '千','万', '十', '百', '千','亿');//可继续追加更高位转换值
    if(!num || isNaN(num)){
        return "零";
    }
    var english = num.toString().split("")
    var result = "";
    for (var i = 0; i < english.length; i++) {
        var des_i = english.length - 1 - i;//倒序排列设值
        result = arr2[i] + result;
        var arr1_index = english[des_i];
        result = arr1[arr1_index] + result;
    }
    //将【零千、零百】换成【零】 【十零】换成【十】
    result = result.replace(/零(千|百|十)/g, '零').replace(/十零/g, '十');
    //合并中间多个零为一个零
    result = result.replace(/零+/g, '零');
    //将【零亿】换成【亿】【零万】换成【万】
    result = result.replace(/零亿/g, '亿').replace(/零万/g, '万');
    //将【亿万】换成【亿】
    result = result.replace(/亿万/g, '亿');
    //移除末尾的零
    result = result.replace(/零+$/, '')
    //将【零一十】换成【零十】
    //result = result.replace(/零一十/g, '零十');//貌似正规读法是零一十
    //将【一十】换成【十】
    result = result.replace(/^一十/g, '十');
    return result;
}

  var show=document.getElementById("show");

  setInterval(function(){
  var now=new Date();
  var nextYear = now.getFullYear() + 1;
  var time=new Date(nextYear,0,1,0,0,0);
      var num=time.getTime()-now.getTime();
      var second=parseInt(num/1000);
       show.innerHTML=convertToChinaNum(second);
      },100)
        </script>
    </body>
</html>

效果预览:https://cnfaq.cn/tryjs/countdown.html

正计时

引自:http://meihuaqizi.com/

<!DOCTYPE html>
<html>
<head>
	<meta charset = "utf-8">
	<!-- 该文件需要下载到本地 --!>
	<script type="text/javascript" src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
	<!-- 该文件需要下载到本地 --!>
	<script type="text/javascript" src = "./animateBackground-plugin.js"></script>
	<!-- 此处的属性startDate指定了正计时开始的时间 --!>
	<script type="text/javascript">
		$(function(){

        		// 读取URL参数中的startDate
        		var urlParams = new URLSearchParams(window.location.search);
        		var startDateParam = urlParams.get('startDate');
        		var startDate = startDateParam || "1995/08/20 00:00:00"; // 如果没有从URL中获取到,使用默认值

        		// 将startDate赋值给script标签的startDate属性,以便后续使用
        		var scripts = document.getElementsByTagName("script"),
        		script_len = scripts.length,
        		script = scripts[script_len - 1]; // 当前加载的script
        		script.setAttribute("startDate", startDate);

			getDate();
			setInterval('getDate()', 1000);//每隔1秒执行一次
		});

			var days,minutes,secondes
			var scripts = document.getElementsByTagName("script"),
			script_len = scripts.length,
			script = scripts[script_len - 1]; //当前加载的script
			function getDate(){
				var birthday = new Date(script.getAttribute("startDate"));
				var date = new Date();
				var date3 = date.getTime() - birthday.getTime();
				// document.write(date3);
				//计算出相差天数
				days=Math.floor(date3/(24*3600*1000));
				//计算出小时数
				var leave1=date3%(24*3600*1000);    //计算天数后剩余的毫秒数
				var hours=Math.floor(leave1/(3600*1000));
				//计算相差分钟数
				var leave2=leave1%(3600*1000);        //计算小时数后剩余的毫秒数
				minutes=Math.floor(leave2/(60*1000));
				//计算相差秒数
				var leave3=leave2%(60*1000);      //计算分钟数后剩余的毫秒数
				//此处原代码有bug,应该仍然下取整
				seconds=Math.floor(leave3/1000);
				// document.write(days+"天"+hours+"时"+minutes+"分"+seconds+"秒  ")
				hours = fix(hours,2);
				minutes = fix(minutes,2);
				seconds = fix(seconds,2);
				show_num("#day",days);
				show_num("#hour",hours);
				show_num("#minute",minutes);
				show_num("#second",seconds);
			}

			function fix(num, length) {
				return ('' + num).length < length ? ((new Array(length + 1)).join('0') + num).slice(-length) : '' + num;
			}

			function show_num(elem,n){
				var it = $(elem+" i");
				var len = String(n).length;
				for(var i=0;i<len;i++){
					if(it.length<=i){
						$(elem).append("<i></i>");
				}
					var num=String(n).charAt(i);
					var y = -parseInt(num)*21; //y轴位置
					var obj = $(elem+" i").eq(i);
					obj.animate({ //滚动动画
						backgroundPosition :'(0 '+String(y)+'px)'
			  			}, 'slow','swing',function(){}
					);
				}
			}
	</script>
	<!-- 该处使用了图片资源文件,该文件需要下载到本地 --!>
	<style type="text/css">
		#div{width:500px; height:40px; line-height:40px; margin:200px auto 20px auto; font-size:20px}
		#div #day{ display:inline-block; line-height:13px; margin:2px 4px 0 4px;}
		#div #hour{ display:inline-block; line-height:13px; margin:2px 4px 0 4px;}
		#div #minute{ display:inline-block; line-height:13px; margin:2px 4px 0 4px;}
		#div #second{ display:inline-block; line-height:13px; margin:2px 4px 0 4px;}
		#div #day i{width:15px;height:21px; display:inline-block; background: url(./number.png) no-repeat; background-position:0 0; text-indent:-999em}
		#div #hour i{width:15px;height:21px; display:inline-block; background: url(./number.png) no-repeat; background-position:0 0; text-indent:-999em}
		#div #minute i{width:15px;height:21px; display:inline-block; background: url(./number.png) no-repeat; background-position:0 0; text-indent:-999em}
		#div #second i{width:15px;height:21px; display:inline-block; background: url(./number.png) no-repeat; background-position:0 0; text-indent:-999em}
	</style>
</head>
<body>
<div id = "div">
	<span id = "day"></span>Days
	<span id = "hour"></span>Hours
	<span id = "minute"></span>Minutes
	<span id = "second"></span>Seconds
</div>
</body>
</html>

效果预览:https://cnfaq.cn/tryjs/counter.html

字符串进化

引自:https://huzidaha.github.io/home/

<!-- 变化字符的显示标签必须命名id为"StrEvolution",也可以是<span/>, <a/>等标签;但其内文本只支持英文字母和逗号,句号 --!>
<h3 id="StrEvolution"> This is a funny action. </h3>

<script>
/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}


/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	var _gen = __webpack_require__(1);

	var _gen2 = _interopRequireDefault(_gen);

	function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

	var isRunning = false;

	var init = function init() {
	  redirectPosts();
	  listen();
	  play();
	};

	function redirectPosts() {
	  var capture = window.location.search.match(/\?post=(\d+)/);
	  var postid = capture ? capture[1] : null;
	  if (postid) {
	    window.location.href = 'https://github.com/livoras/blog/issues/' + postid;
	  }
	}

	function listen() {
	  document.getElementById('StrEvolution').addEventListener('click', function () {
	    if (isRunning) return;
	    play();
	  });
	}

	function play() {
	  var head = document.getElementById('StrEvolution');
	  var headTxt = head.innerText
	  var history = (0, _gen2.default)(headTxt).history;
	  isRunning = true;
	  var i = 0;
	  history.forEach(function (text, i) {
	    setTimeout(function () {
	      head.innerText = text;
	      if (++i === history.length) isRunning = false;
	    }, i * 30);
	  });
	}

	init();

/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

	'use strict';

	/**
	 * Using Genetic Algorithm to generate lots of random strings
	 * and make them evolve towards the target string.
	 *
	 */

	var Genea = __webpack_require__(2);
	var alphabetArr = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ., '.split('');
	var alphabet = function () {
	  var alphabet = {};
	  alphabetArr.forEach(function (ch, i) {
	    alphabet[ch] = i;
	  });
	  return alphabet;
	}();

	function getTargetStr(targetStr) {
	  var binaryStr = '';
	  for (var i = 0, len = targetStr.length; i < len; i++) {
	    var ch = targetStr[i];
	    var chIndex = alphabet[ch];
	    binaryStr += paddingWith0(Number(chIndex).toString(2));
	  }
	  return binaryStr;
	}

	function paddingWith0(num) {
	  while (num.length < 6) {
	    num = '0' + num;
	  }
	  return num;
	}

	function run(str) {
	  var tar = getTargetStr(str);
	  var ga = new Genea({
	    geneLength: tar.length,
	    mutateProbability: 0.5,
	    doneFitness: 1,
	    populationSize: 20,
	    generationsSize: 400,
	    getFitness: function getFitness(gene) {
	      var count = 0;
	      for (var i = 0, len = gene.length; i < len; i++) {
	        if (gene[i] === tar[i]) count++;
	      }
	      var likeness = count / tar.length;
	      return likeness;
	    },
	    onGeneration: function onGeneration(generation, genes) {
	      var max = 0,
	          index = 0;
	      this.fitnesses.forEach(function (fitness, i) {
	        if (fitness > max) {
	          max = fitness;
	          index = i;
	        }
	      });
	      this.history.push(toChars(genes[index]));
	    }
	  });

	  ga.history = [];
	  ga.start();
	  return ga;
	}

	function toChars(gene) {
	  var str = '';
	  while (gene.length) {
	    var ch = '00' + gene.substr(0, 6);
	    gene = gene.substr(6);
	    var chIndex = parseInt(ch, 2);
	    if (chIndex >= alphabetArr.length) {
	      chIndex = Math.floor(Math.random() * (alphabetArr.length - 1));
	    }
	    if (!alphabetArr[chIndex]) console.log(chIndex, parseInt(ch, 2));
	    str += alphabetArr[chIndex];
	  }
	  return str;
	}

	module.exports = run;

/***/ },
/* 2 */
/***/ function(module, exports) {

	'use strict';

	var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

	var Genea = function () {
	  function Genea(config) {
	    _classCallCheck(this, Genea);

	    this.currentGeneration = 0;
	    this.populations = [];
	    this.fitnesses = [];

	    this.mutateProbability = config.mutateProbability || 0.5; // 0 ~ 1
	    this.generationsSize = config.generationsSize || 100;
	    this.populationSize = config.populationSize || 100;
	    this.doneFitness = config.doneFitness || 1; // 0 ~ 1

	    this.geneLength = config.geneLength;
	    this.getFitness = config.getFitness;

	    this.outOfGenerationsSize = config.outOfGenerationsSize || this.outOfGenerationsSize;
	    this.onGeneration = config.onGeneration || this.onGeneration;
	    this.done = config.done || this.done;
	  }

	  _createClass(Genea, [{
	    key: "start",
	    value: function start() {
	      this.initPopulation();
	      this.makeFitnesses();
	      this.select();
	    }
	  }, {
	    key: "initPopulation",
	    value: function initPopulation() {
	      this.currentGeneration = 1;
	      this.populations = [];
	      for (var i = 0, len = this.populationSize; i < len; i++) {
	        var gene = getRandomGene(this.geneLength);
	        this.populations.push(gene);
	      }
	      this.onGeneration(this.currentGeneration, this.populations);
	    }
	  }, {
	    key: "select",
	    value: function select() {
	      if (this.currentGeneration >= this.generationsSize) {
	        return this.outOfGenerationsSize(this.populations, this.fitnesses);
	      }
	      var matches = this.getMatches();
	      if (matches.length > 0) return this.done(matches);
	      this.generateNextGeneration();
	    }
	  }, {
	    key: "makeFitnesses",
	    value: function makeFitnesses() {
	      var _this = this;

	      this.fitnesses = [];
	      this.totalFitness = 0;
	      this.populations.forEach(function (individual, i) {
	        var fitness = _this.getFitness(individual, _this.populations);
	        _this.fitnesses[i] = fitness;
	        _this.totalFitness += fitness;
	      });
	    }
	  }, {
	    key: "getMatches",
	    value: function getMatches() {
	      var _this2 = this;

	      var bests = [];
	      this.populations.forEach(function (individual, i) {
	        var fitness = _this2.fitnesses[i];
	        if (fitness >= _this2.doneFitness) {
	          bests.push({
	            gene: individual,
	            fitness: fitness,
	            pos: i
	          });
	        }
	      });
	      return bests;
	    }
	  }, {
	    key: "generateNextGeneration",
	    value: function generateNextGeneration() {
	      this.currentGeneration++;
	      var oldPopulations = this.populations;
	      var newPopulations = [];
	      for (var i = 0, len = oldPopulations.length; i < len; i++) {
	        var father = this.rotate();
	        var mother = this.rotate();
	        var child = this.crossOver(father, mother);
	        child = this.mutate(child);
	        newPopulations.push(child);
	      }
	      this.populations = newPopulations;
	      this.makeFitnesses();
	      this.onGeneration(this.currentGeneration, this.populations);
	      this.select();
	    }
	  }, {
	    key: "crossOver",
	    value: function crossOver(father, mother) {
	      var pos = Math.floor(father.length * Math.random());
	      var child1 = father.substring(0, pos) + mother.substring(pos);
	      var child2 = mother.substring(0, pos) + father.substring(pos);
	      return this.getFitness(child1) > this.getFitness(child2) ? child1 : child2;
	    }
	  }, {
	    key: "mutate",
	    value: function mutate(child) {
	      var mutateProbability = Math.random();
	      if (mutateProbability < this.mutateProbability) return child;
	      var pos = Math.floor(Math.random() * this.geneLength);
	      var arr = child.split("");
	      arr[pos] = +child[pos] ^ 1;
	      return arr.join("");
	    }
	  }, {
	    key: "rotate",
	    value: function rotate() {
	      var pos = Math.random(); // let's roll!
	      var soFar = 0;
	      for (var i = 0, len = this.fitnesses.length; i < len; i++) {
	        var fitness = this.fitnesses[i];
	        soFar += fitness;
	        if (soFar / this.totalFitness >= pos) {
	          return this.populations[i];
	        }
	      }
	    }
	  }, {
	    key: "done",
	    value: function done() {}
	  }, {
	    key: "onGeneration",
	    value: function onGeneration() {}
	  }, {
	    key: "outOfGenerationsSize",
	    value: function outOfGenerationsSize() {}
	  }]);

	  return Genea;
	}();

	function getRandomGene(len) {
	  var gene = "";
	  for (var i = 0; i < len; i++) {
	    gene += Math.floor(Math.random() * 100) % 2 === 0 ? "1" : "0";
	  }
	  return gene;
	}

	module.exports = Genea;

/***/ }
/******/ ]);
</script>

效果预览:https://cnfaq.cn/tryjs/stringchanges.html

旋转地球仪

引自:http://www.gbtags.com/gb/rtreplayerpreview/369.htm

<!-- 这段javascript代码必须顶开头写 --!>
<script>
eval(z='p="<"+"pre>"/*  ############   */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/* ##############      */42kty24wrt413n243n\
9h243pdxt41csb yz/*#################    * */43iyb6k43pk7243nm\
r24".split(4)){/* ###########*            # */for(a in t=pars\
eInt(n[y],36)+/**#############           ### */(e=x=r=[]))for\
(r=!r,i=0;t[a/*  *############            ### */]>i;i+=.05)wi\
th(Math)x-= /*   #############            *#*  */.05,0>cos(o=\
new Date/1e3/*   #######*                 *### */+x/PI)&&(e[~\
~(32*sin(o)*/*      ####*              ####### */sin(.5+y/7))\
+60] =-~ r);/*          *####*        *####### */for(x=0;122>\
x;)p+="   *#"/*          ########*       *### */[e[x++]+e[x++\
]]||(S=("eval"/*         ############*     # */+"(z=\'"+z.spl\
it(B = "\\\\")./*        *#######         # */join(B+B).split\
(Q="\'").join(B+Q/*       ######*       * */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/*     *##*         * */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)')//m1k\
</script>

效果预览:https://cnfaq.cn/tryjs/earth.html

包含行星环的行星模型(带光影效果)

应用示例

在<body>中加入加入以下代码,以在背景位置生成相应的效果展示:

    <div id="container" style="position:absolute; text-align:center; top: 0; z-index: 0; width: 100%; height: 100%;"></div>
    <script src="./js/three.min.js"></script>
    <script src="./js/planetEffect.js"></script>

注意:three.js的版本需要早期版本,例如:<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.min.js"></script>

效果JS文件

对应的JS文件(planetEffect.js)内容如下:

注意:该脚本依赖了Three.js库,如之前应用示例中所示,需要提前引入。

var container = document.getElementById("container");
var width = container.clientWidth;
var height = container.clientHeight;
var aspect = width / height;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
container.appendChild(renderer.domElement);

var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(50, aspect, 0.1, 1000);
camera.position.z = 500

system = new THREE.Group(); // planetary system

scene.add(
  new THREE.AmbientLight(0xFFFFFF, 0.2)
);

var light = new THREE.DirectionalLight(0xFFFFFF, 2.5);
light.position.set(1500, 2500, 0);
scene.add(light);

var material = new THREE.MeshLambertMaterial({
  color: 0x0C2D4D
});

var planet = new THREE.Mesh(
  new THREE.IcosahedronGeometry(100, 3),
  material
);

for (var i = 0; i < planet.geometry.vertices.length; i++)
  planet.geometry.vertices[i].multiplyScalar(
    Math.random() * 0.05 + 0.95
  );

planet.geometry.computeFlatVertexNormals();
system.add(planet);

var asteroids = new THREE.Group();

for (var p = 0; p < Math.PI * 2; p = p + Math.random() * 0.15) {
  var asteroid = new THREE.Mesh(
    new THREE.IcosahedronGeometry(8, 0),
    material
  );

  var size = Math.random() * 0.5;
  for (var i = 0; i < asteroid.geometry.vertices.length; i++)
    asteroid.geometry.vertices[i].multiplyScalar(
      Math.random() * 0.5 + size
    );

  rand = Math.random() * 60 - 30;
  asteroid.position.set(200 * Math.sin(p) + rand, rand, 200 * Math.cos(p) + rand);

  asteroid.geometry.computeFlatVertexNormals();
  asteroids.add(asteroid);
}

system.add(asteroids);

system.rotation.x = 0.1;
system.rotation.y = -.3;
system.rotation.z = -0.4;

scene.add(system);

for (i = 0; i < 10; i++) {
  particles = new THREE.Points(
    new THREE.Geometry(),
    new THREE.PointsMaterial({
      size: Math.random() * 5
    })
  );
  for (j = 0; j < 20; j++) {
    var vertex = new THREE.Vector3();
    vertex.x = Math.random() * width * 1.1 - width * 1.1 / 2;
    vertex.y = Math.random() * height * 1.1 - height * 1.1 / 2;
    vertex.z = -500;
    particles.geometry.vertices.push(vertex);
    particles.material.color.setScalar(Math.random() * 0.4 + 0.2);
  }
  scene.add(particles);
}

function render() {
  requestAnimationFrame(render);

  planet.rotation.y += 0.001;
  planet.rotation.z -= 0.0005;

  asteroids.rotation.y += 0.003;

  renderer.render(scene, camera);
}

render();

效果预览

https://cnfaq.cn/tryjs/plant.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李小白杂货铺

打赏是一种友谊,让我们更亲密。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值