彩圈
结果图:
<!-- 页面中唯一固定的dom元素,是控制手动和自动的按钮 -->
<div class="button" data-id="handle">手动</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="../js/index.js"></script>
/* 设置body背景色 */
body{
background-color: #000;
overflow:hidden;
}
/* 按钮的样式 */
.button{
width:100px;
height:30px;
/* 文字水平居中 */
text-align:center;
/* 文字垂直居中 */
line-height:30px;
/* 设置字体颜色为白色 */
color:#fff;
/* 设置字体粗细 */
font-weight:bold;
/* 设置字体大小 */
font-size:18px;
/* 设置背景颜色 */
background-color: aqua;
/* 设置圆角效果 */
border-radius:10px;
/* 设置边框 */
border:1px solid #ccc;
/* 设置鼠标样式 */
cursor: pointer;
/* 因为彩圈是在全屏任意出现,当他出现在按钮上时,保证按钮在它的上面,这就要设置z-index,它必须有定位才会生效 */
position:absolute;
z-index:99;
left:20px;
top:20px;
/* 设置用户不可选择 */
user-select:none;
}
/* 添加的彩圈的样式 */
img{
position:absolute;
/* 大小 */
width:70px;
height:70px;
user-select: none;
}
(function(){
// 一、用于记录图片资源地址的
var currentSrc = -1;
// 自动播放的定时器 当改为手动时,要停止
var timer = null;
// 二、获取按钮的dom元素
var btn = document.getElementsByClassName('button')[0];
// 三、程序入口函数;进入程序自动执行自动的动画
var init = function(){
auto();
}
// 四、为btn绑定点击事件
btn.onclick = function(){
// 1.获取自定义属性的值
var data = btn.dataset.id;
// 2.判断自定义属性值,若为手动
if(data === "handle"){
// 手动,牵扯了三个事件:鼠标点击 鼠标移动 鼠标抬起
// 清除自动的定时器
clearInterval(timer);
// 将按钮的文字以及自定义属性改为自动
btn.dataset.id = "auto";
btn.innerHTML = "自动";
// 这里给document绑定事件
document.onmousedown = function(ed){
// 鼠标按下之后,绑定鼠标移动事件
// 主要就是鼠标移动事件
document.onmousemove = function(em){
// console.log(this);//document;即谁调用的this就指向谁
// 鼠标移动随着鼠标的位置来产生img,小圆圈
// 1.获取移动事件发生时,鼠标距离浏览器左边的距离和距离上边的距离
var left = em.clientX;
var top = em.clientY;
// 2.确定这次图片的src 0 1 2 3 4; 0 1 2 3 4.。。的顺序;因为这个src自动的时候也需要,故把他写在外面
currentSrc = (currentSrc + 1) % 5;
// 3.创造img
circleImg(left,top,currentSrc,false);
}
// 鼠标抬起事件
document.onmouseup = function(ep){
// 鼠标抬起之后应该,消除鼠标移动事件
document.onmousemove = null;
}
}
}else{
// 将按钮的文字以及自定义属性改为手动
btn.dataset.id = "handle";
btn.innerHTML = "手动";
// 取消鼠标按下的事件
document.onmousedown = null;
// 自动函数启动
auto();
}
}
/**辅助函数
* 用于图片元素的生成以及动画事件的绑定
* @param {距离左边} left
* @param {距离上边} top
* @param {图片资源的地址} source
* @param {是否自动} auto
*/
function circleImg(left,top,source,auto){
// 1.创建img元素
var img = document.createElement('img');
// 2.设置img元素的left top 以及资源的地址
img.style.left = left + 'px';
img.style.top = top + 'px';
img.src = `../img/${source}.png`;
// 3.将他添加到body中
document.body.appendChild(img);
// 4.为它添加动画函数 jquery中的动画函数
// 这里是jquery库里面的函数,需要jquery对象来调用 不可以用dom对象
// animate传入的是一个对象参数,对象参数中并没有this;而这里的this应该是circleImg函数作用域链中的,谁调用的circleImg
// console.log(this);//window
// jQuery中animate中对象参数使用的$(this),并不指向调用animate的元素,因为他是当作实参传入的,所以这里的$(this)其实指向的是调用animate的元素所在函数/或者事件的调用者
// 具体见:https://blog.csdn.net/weixin_44136516/article/details/88388821
// 回调函数中的this一定指向的是调用animate的元素,因为this谁调用的就只想谁,最后的回调函数是该元素调用的;通过控制台打印,也验证了,输出的正是$(img:last)的dom元素;
// 如果是true则说明时自动
if(auto){
// todo 动画执行完成的处理
$('img:last').animate({ // 这个DOM元素要开始做动画了
width: '0px',
height: '0px',
top: top + 35 + 'px',
left: left + 35 + 'px'
}, 1500, function () {
// 动画执行完成
document.body.removeChild(this)
})
}else{
// 手动的动画
$('img:last').animate({
// 最后的css;在规定的时间内慢慢变到这个样式
width:'0px',
height:'0px',
top: top - 240 + 'px'
},1500,function(){
// 做完动画后的回调函数;昨晚动画应该把他清除
// console.log(this)
document.body.removeChild(this);
})
}
}
// 自动,牵扯计时器
function auto(){
// 每隔一段时间就产生一个img对象。第一个对象是在页面中随机产生的;存在四个边界
// innerheight 返回窗口的文档显示区的高度。innerwidth 返回窗口的文档显示区的宽度。
// 一个整数型的值表示窗口的布局视口宽度是以像素为单位的
// 产生的img宽高都是70,所以为了不让他超出视口,位置,要留出70像素
// x:0-(window.innerWidth-70);y:0-(window.innerHeight-70);
var x = Math.random() * (window.innerWidth - 70);
var y = Math.random() * (window.innerHeight - 70);
// 设置锁,确保x y加的正值还是负值
var xLock = false;
var yLock = false;
timer = setInterval(function(){
// 当x横坐标小于最小值了,应该让他加
if(x <= 0){
xLock = true;
}else if(x >= window.innerWidth - 70) {
// 当x横坐标大于最大值,x开始减
xLock = false;
}
// 当y横坐标小于最小值了,应该让他加
if(y <= 0){
yLock = true;
}else if(y >= window.innerHeight - 70) {
// 当y横坐标大于最大值,y开始减
yLock = false;
}
currentSrc = (currentSrc + 1) % 5;
circleImg(x,y,currentSrc,true);
// 根据上面设置的锁,来判断是加还是减
if(xLock){
// 当为true时,x应该加;范围10-20
x += Math.random() * 10 + 10
}else{
x -= Math.random() * 10 + 10
}
if(yLock){
// 当为true时,x应该加;范围10-20
y += Math.random() * 10 + 10
}else{
y -= Math.random() * 10 + 10
}
},50)
}
auto();
}())