JavaScript 雷达

来源:互联网 发布:linux图形界面 编辑:程序博客网 时间:2024/04/24 05:19
<!DOCTYPE html><html>    <head>        <meta charset="utf8">        <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">        <meta name="viewport" content="width=device-width, initial-scale=1.0">        <meta name="keywords" content="Orb trails">        <meta name="description" content="Orb trails">        <title>Orb trails</title>        <style>            body {                background: black;                color: #aaa;                font: 12px/20px helvetica, arial, sans-serif;                overflow: hidden;            }            #control-panel {                position: absolute;                padding: 10px;                border: 1px dotted Cornsilk;                border-radius: 10px;                background-color: rgba(0,0,0,.5);            }            #control-panel button {                margin: 5px 10px 5px 0;                width: 60px;            }            #control-panel input {                /* 添加这句后按钮和文字才会对齐 */                vertical-align:middle;            }        </style>    </head>    <body>        <div id="control-panel">            Click and drag to make more!            <br/>            <label>Direction: </label>            <input type="radio" name="direction" value="clockwise" checked/>Clockwise            <input type="radio" name="direction" value="counterclockwise">Counterclockwise            <br/>            <label>Angular Speed: </label>            <input type="radio" name="stepType" value="same" checked />Same            <input type="radio" name="stepType" value="random"/>Random            <br/>            <label>Trails: </label>            <input type="checkbox" id="trail" checked/>            <br/>            <button id="init">Init</button>            <button id="clear">Clear</button>            <button id="switchState">Pause</button>            <br/>            我在残酷的现实中反复挣扎,<br/>            残酷的现实却让我无法自拔。        </div>        <canvas id="canvas">Your browser can not support canvas</canvas>        <script>            var canvas = document.getElementById("canvas");            var ctx = canvas.getContext("2d");            var halfPI = Math.PI / 2;            var doublePI = Math.PI * 2;            //天体线条笔帽            var lineCap = "round";            //用来制作天体尾巴的蒙版透明度(透明度越低,尾巴越长)            var maskAlpha = 0.1;            //初始化的天体个数            var initCount = 30;            //每帧一次性更新和渲染的次数            var onceUpdateAndRenderTimes = 4;            //为了防止粒子被添加的太多,这里设置只有x或y的差值大于该阀值才能被添加            var offsetThreshold = 5;            //画布中心点坐标            var cx;            var cy;            //旋转方向[clockwise(顺时针), counterClockwise(逆时针)]            var direction = "clockwise";            //角速度步长[same(相同角速度), random(随机角速度)]            var stepType = "same";            //是否显示天体的尾巴            var isTrails = true;            //是否暂停            var isPause = false;            //天体粒子数组            var orbs = [];            //在[min,max]中随机选取一个数            function randomAtRange(obj) {                return Math.random() * (obj.max - obj.min) + obj.min;            }            //画线条            function strokeLine(x1, y1, x2, y2) {                ctx.beginPath();                ctx.moveTo(x1, y1);                ctx.lineTo(x2, y2);                ctx.stroke();            }            //天体粒子            var Orb = function(x, y) {                //宽度范围                var widthRange = {min: 1, max: 3};                //等角速度的时候的步长                var sameRadianStep = 0.01;                //随机角速度时候的步长                var randomRadianRange = {min: 0.005, max: 2 * sameRadianStep};                //上一次的位置                var lastX = x;                var lastY = y;                //与中心的距离(右下为正)                var dx = x - cx;                var dy = y - cy;                //距画布中心的半径                var radius = Math.sqrt(dx * dx + dy * dy);                //宽度                var width = randomAtRange(widthRange);                //每帧步长                var step = 0;                //Math.atan2(y,x)返回(-Math.PI,Math.PI], 返回(x,y)与0点钟方向的夹角, 顺时针方向为正。但由于画布是右下方为正,等价于做垂直镜像                var radian = Math.atan2(dx, dy);                //色相                var hue;                //绕中心旋转速度类型[same(等角速度)、random(随机)]                this.resetStepType = function() {                    if(stepType === "same") {                        step = sameRadianStep;                    } else {                        step = randomAtRange(randomRadianRange);                    }                }                //判断当前点是否与给定点离的很近                this.isNear = function(pointX, pointY) {                    if(Math.abs(pointX - x) < offsetThreshold && Math.abs(pointY - y) < offsetThreshold) {                        return true;                    }                    return false;                }                //当画布大小被改变的时候                this.resetPos = function() {                    x = lastX = cx + radius * Math.sin(radian);                    y = lastY = cy + radius * Math.cos(radian);                }                this.update = function() {                    lastX = x;                    lastY = y;                    x = cx + radius * Math.sin(radian);                    y = cy + radius * Math.cos(radian);                    hue = 360 * radian / doublePI;                    if(direction === "clockwise") {                        radian = (radian - step) % doublePI;                    } else {                        radian = (radian + step) % doublePI;                    }                }                this.render = function() {                    ctx.strokeStyle = "hsla(" + hue + ",100%,50%,1)";                    ctx.lineWidth = width;                    strokeLine(lastX, lastY, x, y);                }                this.resetStepType();                this.resetPos();            }            //初始化所有天体            function initOrbs() {                var len = Math.min(cx, cy);                var step = len / (initCount+1);                orbs = [];                for(var i=0, offsetY = cy - step; i<initCount; i++, offsetY -= step) {                    orbs.push(new Orb(cx, offsetY));                }            }            function init() {                onResize();                var directionRadios = document.getElementsByName("direction");                var stepTypeRadios = document.getElementsByName("stepType");                var trailCb = document.getElementById("trail");                var initBtn = document.getElementById("init");                var clearBtn = document.getElementById("clear");                var switchStateBtn = document.getElementById("switchState");                window.addEventListener("resize", onResize);                //指定事件是否在捕获(true)或冒泡(false)阶段执行。true的触发顺序总是在false之前                canvas.addEventListener("mousedown", onMouseDown, false);                canvas.addEventListener("mouseup", onMouseUp, false);                canvas.addEventListener("mouseout", onMouseOut, false);                //旋转方向                for(var i=0; i<directionRadios.length; i++) {                    //这里用change或者click事件均可以                    directionRadios[i].addEventListener("change", function(){                        direction = event.target.value;                    });                }                //角速度类型                for(var i=0; i<stepTypeRadios.length; i++) {                    //这里用change或者click事件均可以                    stepTypeRadios[i].addEventListener("change", function(){                        stepType = event.target.value;                        for(var i=0; i<orbs.length; i++) {                            orbs[i].resetStepType();                        }                    });                }                //是否显示轨迹                trailCb.addEventListener("change", function() {                    isTrails = event.target.checked;                });                //清除所有天体                clearBtn.addEventListener("click", function() {                    orbs = [];                    //这里还要清除一下画布,否则上面还有颜色残留,只是用某个透明度的黑覆盖而已                    ctx.clearRect(0, 0, canvas.width, canvas.height);                });                //初始化一部分的天体                initBtn.addEventListener("click", initOrbs);                //切换天体的运行和停止状态                switchStateBtn.addEventListener("click", function() {                    isPause = !isPause;                    console.log(isPause);                    switchStateBtn.innerHTML = isPause ? "Pause" : "Start";                });                ctx.lineCap = lineCap;                initOrbs();                loop();            }            function loop() {                if(!isPause) {                    if(isTrails) {                        //使用带透明度的颜色来填充就相当于色彩叠加了                        ctx.fillStyle = "rgba(0,0,0," + maskAlpha + ")";                        ctx.fillRect(0, 0, canvas.width, canvas.height);                    } else {                        ctx.clearRect(0, 0, canvas.width, canvas.height);                    }                    for(var i=0; i<orbs.length; i++) {                        for(var j=0; j<onceUpdateAndRenderTimes; j++) {                            orbs[i].update();                            orbs[i].render();                        }                    }                }                requestAnimationFrame(loop);            }            //有一个瑕疵是暂停的话,然后resize,所有的点都会消失            function onResize() {                canvas.width = window.innerWidth;                canvas.height = window.innerHeight;                cx = canvas.width / 2;                cy = canvas.height / 2;                for(var i=0; i<orbs.length; i++) {                    orbs[i].resetPos();                }            }            function onMouseDown() {                canvas.addEventListener("mousemove", onMouseMove);                onMouseMove();            }            function onMouseMove() {                //event.offsetX 等价于 event.pageX - canvas.offsetLeft                var x = event.offsetX;                var y = event.offsetY;                for(var i=0; i<orbs.length; i++) {                    if(orbs[i].isNear(x, y)) {                        return;                    }                }                orbs.push(new Orb(x, y));            }            function onMouseUp() {                canvas.removeEventListener("mousemove", onMouseMove);            }            function onMouseOut() {                canvas.removeEventListener("mousemove", onMouseMove);            }            init();        </script>    </body></html>

这里写图片描述

1 0
原创粉丝点击