情人节代码

 效果图

 代码



<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8" />
  <title>爱你一万年</title>
  <!-- 弯月亮 荣誉出品,[email protected] -->
  <style>
    #wrapper {
      height: 35rem;
      width: 100%;
      position: relative;
      overflow: hidden;
      background: url(https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1568263949912&di=5229baf0d8472ab65a023691894896dc&imgtype=0&src=http%3A%2F%2Fbpic.588ku.com%2Felement_origin_min_pic%2F16%2F06%2F25%2F11576df4a2f1f4c.jpg);
      
      color: #ffffff82;
      font-size: 14px;
      text-shadow: 1px 1px #000;
      animation:change 1s infinite;
    }
    .right {
      /*left: 100%;*/
      position: absolute;
      visibility: hidden;
      white-space: nowrap;
      /*left: 700px;*/
      transform: translateX(700px);
    }
    .left {
      position: absolute;
      white-space: nowrap;
      user-select: none;
      transition: transform 7s linear; /* 时间相同 越长的弹幕滑动距离越长 所以越快~ */
    }
    input {
      position: absolute;
      bottom: 10px;
      left: 20rem;
      width: 300px;
      height: 26px;
    }

    button {
      position: absolute;
      bottom: 8px;
      left: 40rem;
      width: 100px;
      height: 38px;
      border-radius: 10px;
      font-size: 16px;
      background-color: #FFB6C1;
    }
    span {
    	 left: 17rem;
    	 font-size: 15px;
    	 /*color:red;*/
    }
    @keyframes change {
				0% {
					color: #333;
				}
				25% {
					color: #ff0;
				}
				50% {
					color: #f60;
				}
				75% {
					color: #cf0;
				}
				100% {
					color: #f00;
				}
			}
  </style>
</head>
<body>
<div id="wrapper">
  
  
  	 <input type="text" value="爱你一万年">
 	 <button>爱心一击</button>
  
</div>

<script>
	     //鼠标点击出现爱心特效
		(function(window,document,undefined){
			var hearts = [];
			window.requestAnimationFrame = (function(){
				return window.requestAnimationFrame ||
				window.webkitRequestAnimationFrame ||
				window.mozRequestAnimationFrame ||
				window.oRequestAnimationFrame ||
				window.msRequestAnimationFrame ||
				function (callback){
					setTimeout(callback,1000/60);
				}
			})();
			init();
			function init(){
				css(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: absolute;}.heart:after{top: -5px;}.heart:before{left: -5px;}");
				attachEvent();
				gameloop();
			}
			function gameloop(){
				for(var i=0;i<hearts.length;i++){
					if(hearts[i].alpha <=0){
						document.body.removeChild(hearts[i].el);
						hearts.splice(i,1);
						continue;
					}
					hearts[i].y--;
					hearts[i].scale += 0.004;
					hearts[i].alpha -= 0.013;
					hearts[i].el.style.cssText = "left:"+hearts[i].x+"px;top:"+hearts[i].y+"px;opacity:"+hearts[i].alpha+";transform:scale("+hearts[i].scale+","+hearts[i].scale+") rotate(45deg);background:"+hearts[i].color;
				}
				requestAnimationFrame(gameloop);
			}
			function attachEvent(){
				var old = typeof window.οnclick==="function" && window.onclick;
				window.onclick = function(event){
					old && old();
					createHeart(event);
				}
			}
			function createHeart(event){
				var d = document.createElement("div");
				d.className = "heart";
				hearts.push({
					el : d,
					x : event.clientX - 5,
					y : event.clientY - 5,
					scale : 1,
					alpha : 1,
					color : randomColor()
				});
				document.body.appendChild(d);
			}
			function css(css){
				var style = document.createElement("style");
				style.type="text/css";
				try{
					style.appendChild(document.createTextNode(css));
				}catch(ex){
					style.styleSheet.cssText = css;
				}
				document.getElementsByTagName('head')[0].appendChild(style);
			}
			function randomColor(){
				return "rgb("+(~~(Math.random()*255))+","+(~~(Math.random()*255))+","+(~~(Math.random()*255))+")";
			}
		})(window,document);
</script>
<script>
/**
 * 设置 弹幕DOM池 每一个通道最多六条弹幕
**/

const MAX_DM_COUNT = 10;
const CHANNEL_COUNT = 10;

let domPool = [];
let danmuPool = [
  // '爱你一万年',

];
let hasPosition = [];

/**
 * 做一下初始化工作
 */
function init() {
  let wrapper = document.getElementById('wrapper')
  // 先new一些span 重复利用这些DOM
  for (let j = 0; j < CHANNEL_COUNT; j++) {
    let doms = [];
    for (let i = 0; i < MAX_DM_COUNT; i++) {
      // 要全部放进wrapper
      let dom = document.createElement('span');
      wrapper.appendChild(dom);
      // 初始化dom的位置 通过设置className
      dom.className = 'right';
      // DOM的通道是固定的 所以设置好top就不需要再改变了
      dom.style.top = j * 40 + 'px';
      // dom.style.left=300+'px'
      // dom.style.background='red'
      // 放入改通道的DOM池
      doms.push(dom);
      // 每次到transition结束的时候 就是弹幕划出屏幕了 将DOM位置重置 再放回DOM池
      dom.addEventListener('transitionend', () => {
        dom.className = 'right';
        // dom.style.transition = null;
        // dom.style.left = null;
        dom.style.transform = null;

        domPool[j].push(dom);
      });
    }
    domPool.push(doms);
  }
  // hasPosition 标记每个通道目前是否有位置
  for (let i = 0; i < CHANNEL_COUNT; i++) {
    hasPosition[i] = true;
  }
}

/**
 * 获取一个可以发射弹幕的通道 没有则返回-1
 */
function getChannel() {
  for (let i = 0; i < CHANNEL_COUNT; i++) {
    if (hasPosition[i] && domPool[i].length) return i;
  }
  return -1;
}

/**
 * 根据DOM和弹幕信息 发射弹幕
 */
function shootDanmu(dom, text, channel) {
  console.log('biu~ [' + text + ']');
  dom.innerText = text;
  // 如果为每个弹幕设置 transition 可以保证每个弹幕的速度相同 这里没有保证速度相同
  // dom.style.transition = `transform ${7 + dom.clientWidth / 100}s linear`;

  // dom.style.left = '-' + dom.clientWidth + 'px';
  // 设置弹幕的位置信息 性能优化 left -> transform
  dom.style.transform = `translateX(${-dom.clientWidth}px)`;
  dom.className = 'left';
  
  hasPosition[channel] = false;
  // 弹幕全部显示之后 才能开始下一条弹幕
  // 大概 dom.clientWidth * 10 的时间 该条弹幕就从右边全部划出到可见区域 再加1秒保证弹幕之间距离
  setTimeout(() => {
    hasPosition[channel] = true;
  }, dom.clientWidth * 10 + 1000);
}

window.onload = function() {

  init();

  // 为input和button添加事件监听
  let btn = document.getElementsByTagName('button')[0];
  let input = document.getElementsByTagName('input')[0];
  btn.addEventListener('click', () => {
    input.value = input.value.trim();
    if (input.value) danmuPool.push(input.value);input.value=''
  })
  input.addEventListener('keyup', (e) => {
    if (e.key === 'Enter' && (input.value = input.value.trim())) {
      danmuPool.push(input.value);input.value=''
    }
  })
  // 每隔1ms从弹幕池里获取弹幕(如果有的话)并发射
  setInterval(() => {
    let channel;
    if (danmuPool.length && (channel = getChannel()) != -1) {
      let dom = domPool[channel].shift();
      domPool[channel].push(dom)
      let danmu = danmuPool.shift();
      danmuPool.push(danmu);
      shootDanmu(dom, danmu, channel);
    }
  }, 1);

}
        
</script>
</body>
</html>
发布了7 篇原创文章 · 获赞 1 · 访问量 854

猜你喜欢

转载自blog.csdn.net/sll9711/article/details/100765451