2.12.1_拖动多边形对象

来源:互联网 发布:淘宝卖家多少分一个钻 编辑:程序博客网 时间:2024/06/07 03:13

2.12.1_拖动多边形对象

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title>可拖动的多边形对象</title>        <style>            body{                background: #eee;            }            #controls{                position: absolute;                left: 25px;                top: 25px;            }            #canvas{                background: #fff;                cursor: pointer;                margin-left: 10px;                margin-top: 10px;                box-shadow: 4px 4px 8px rgba(0,0,0,0.5);                -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);                -moz-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);            }        </style>    </head>    <body>        <canvas id="canvas" width="1050" height="600"></canvas>        <div id="controls">            描边的颜色:            <select id="strokeStyleSelect">                <option value="red">red</option>                <option value="green">green</option>                <option value="blue">blue</option>                <option value="orange">orange</option>                <option value="cornflowerblue" selected>cornflowerblue</option>                <option value="goldenrod">goldenrod</option>                <option value="navy">navy</option>                <option value="purple">purple</option>            </select>            填充的颜色:            <select id="fillStyleSelect">                <option value="red">red</option>                <option value="green">green</option>                <option value="blue">blue</option>                <option value="orange">orange</option>                <option value="cornflowerblue" selected>cornflowerblue</option>                <option value="goldenrod">goldenrod</option>                <option value="navy">navy</option>                <option value="purple">purple</option>            </select>            多边形边数:            <select id="sidesSelect">                <option value="3" selected>3</option>                <option value="4">4</option>                <option value="5">5</option>                <option value="6">6</option>                <option value="7">7</option>                <option value="8">8</option>            </select>            起始角度:            <input id="startAngleSelect" type="number" value="0" />            填充:            <input id="fillCheckbox" type="checkbox" checked />            <input id="eraseAllButton" type="button" value="擦除全部线条" /><br />            可拖动:<input id="editCheckbox" type="checkbox" />            指示线:            <input id="guidewireCheckbox" type="checkbox"/>        </div>    </body>    <script>        var canvas = document.getElementById('canvas'),            context = canvas.getContext('2d'),            strokeStyleSelect = document.getElementById('strokeStyleSelect'),            fillStyleSelect = document.getElementById('fillStyleSelect'),            sidesSelect = document.getElementById('sidesSelect'),            startAngleSelect = document.getElementById('startAngleSelect'),            fillCheckbox = document.getElementById('fillCheckbox'),            guidewireCheckbox = document.getElementById('guidewireCheckbox'),            eraseAllButton = document.getElementById('eraseAllButton'),            editCheckbox = document.getElementById('editCheckbox'),            drawingSurfaceImageData,            mousedown ={},            rubberbandRect = {},            dragging = false,            draggingOffsetX,            draggingOffsetY,            filled= fillCheckbox.checked,            sidesNum = parseInt(sidesSelect.value),            startAngle = parseInt(startAngleSelect.value)*Math.PI/180, //起始角度转弧度            guidewires = false,            editing = false,            polygons = []; //用于保存绘制好的多边形对象集合            //初始化            context.strokeStyle = strokeStyleSelect.value;            context.fillStyle = fillStyleSelect.value;            context.shadowColor = 'rgba(0,0,0,0.4)';            context.shadowOffsetX = 2;            context.shadowOffsetY = 2;            context.shadowBlur = 4;            drawGrid('lightgray',10,10);            //事件处理器            canvas.onmousedown = function (e){                var loc = windowToCanvas(e.clientX,e.clientY);                e.preventDefault();                if(editing){ //可拖动状态                    polygons.forEach(function(polygon){                        polygon.createPath(context);                        if(context.isPointInPath(loc.x,loc.y)){                            startDragging(loc);                            dragging = polygon;                            draggingOffsetX = loc.x - polygon.x;                            draggingOffsetY = loc.y - polygon.y;                            return;                        }                    })                }else{ //可绘制状态                    startDragging(loc);                    dragging = true;                }            }            canvas.onmousemove = function(e){                var loc = windowToCanvas(e.clientX,e.clientY);                e.preventDefault();                if(editing&&dragging){  //处于可拖动状态并且有存在可以拖动的对象                    dragging.x = loc.x - draggingOffsetX;                    dragging.y = loc.y - draggingOffsetY;                    context.clearRect(0,0,canvas.width,canvas.height);                    drawGrid('lightgray',10,10);                    drawPolygons();                }else{                    if(dragging){ //处于绘制的状态                        restoreDrawingSurface();                        updateRubberband(loc,sidesNum,startAngle);                        if(guidewires){                            drawGuidewires(loc.x,loc.y);                        }                    }                }            }            canvas.onmouseup = function(e){                var loc = windowToCanvas(e.clientX,e.clientY);                dragging = false;                if(editing){                }else{                    restoreDrawingSurface();                    updateRubberband(loc,sidesNum,startAngle);                }            }            guidewireCheckbox.onchange = function(){                guidewires = guidewireCheckbox.value;            }            fillStyleSelect.onchange = function(){                context.fillStyle= fillStyleSelect.value;            }            strokeStyleSelect.onchange = function(){                context.strokeStyle = strokeStyleSelect.value;            }            editCheckbox.onchange = function (){                if(editCheckbox.checked){                    startEditing();                }else{                    stopEditing();                }            }            sidesSelect.onchange = function (){                sidesNum = parseInt(sidesSelect.value);            }            startAngleSelect.onchange =function(){                startAngle = parseInt(startAngleSelect.value)*Math.PI/180            }            fillCheckbox.onchange = function(){                filled= fillCheckbox.checked;            }            eraseAllButton.onclick = function (){                context.clearRect(0,0,canvas.width,canvas.height);                drawGrid('lightgray',10,10);                saveDrawingSurface();                polygons = [];            }            //重绘所有的多边形            function drawPolygons(){                polygons.forEach(function(polygon){                    drawPolygon(polygon);                })            }            //开始编辑            function startEditing(){                canvas.style.cursor = 'pointer';                editing = true;            }            //结束编辑            function stopEditing(){                canvas.style.cursor = 'crosshair';                editing = false;            }            //绘制指示线            function drawGuidewires(x,y){                context.save();                context.strokeStyle = 'rgba(0,0,230,0.4)';                context.lineWidth = 0.5;                drawVerticalLine(x);                drawHorizontalLine(y);                context.restore();            }            //绘制垂线            function drawVerticalLine(x){                context.beginPath();                context.moveTo(x+0.5,0);                context.lineTo(x+0.5,context.canvas.height);                context.stroke();            }            //绘制水平线            function drawHorizontalLine(y){                context.beginPath();                context.moveTo(0,y+0.5);                context.lineTo(context.canvas.width,y+0.5);                context.stroke();            }            //实时更新视图            function updateRubberband(loc,sidesNum,startAngle){                updateRubberRectangle(loc);                drawRubberbandShape(loc,sidesNum,startAngle);            }            //维护一个四边形            function updateRubberRectangle(loc){                rubberbandRect.width = Math.abs(loc.x - mousedown.x);                rubberbandRect.height = Math.abs(loc.y - mousedown.y);                if(loc.x>mousedown.x){                    rubberbandRect.left = mousedown.x;                }else{                    rubberbandRect.left = loc.x;                }                if(loc.y> mousedown.y){                    rubberbandRect.top = mousedown.y;                }else{                    rubberbandRect.top = loc.y;                }            }            //绘制多边形            function drawRubberbandShape(loc,sidesNum,startAngle){                var polygon = new Polygon(mousedown.x,                                          mousedown.y,                                          rubberbandRect.width,                                          sidesNum,                                          startAngle,                                          context.strokeStyle,                                          context.fillStyle,                                          filled                );                drawPolygon(polygon);                if(!dragging){ //如果绘制多边形后监测以鼠标抬起了,也就相当于dragging为false时,把绘制好的多边形加入到                            //保存的polygos对象中                    polygons.push(polygon);                }            }            //绘制多边形            function drawPolygon(polygon){                context.beginPath();                polygon.createPath(context);                polygon.stroke(context);                if(polygon.filled){                    polygon.fill(context);                }            }            //多边形各个角的构造函数            var Point = function (x,y){                this.x = x;                this.y = y;            }            //多边形的构造函数            var Polygon = function (centerX,centerY,radius,sides,startAngle,strokeStyle,fillStyle,filled){                this.x = centerX;                this.y = centerY;                this.radius = radius;                this.sides = sides;                this.startAngle = startAngle;                this.strokeStyle = strokeStyle;                this.fillStyle = fillStyle;                this.filled = filled;            }            //多边形的构造函数的原型函数            Polygon.prototype = {                getPoints:function(){                    var points = [],                        angle = this.startAngle || 0;                    for(var i =0;i<this.sides;i++){                        points.push(new Point(this.x+this.radius*Math.cos(angle),                                             this.y-this.radius*Math.sin(angle)));                        angle +=2*Math.PI/this.sides;                    }                    return points;                },                createPath:function(context){                    var points = this.getPoints();                    context.beginPath();                    context.moveTo(points[0].x,points[0].y);                    for(var i=1;i<this.sides;i++){                        context.lineTo(points[i].x,points[i].y);                    }                    context.closePath();                },                stroke:function (context){                    context.save();                    this.createPath(context);                    context.strokeStyle = this.strokeStyle;                    context.stroke();                    context.restore();                },                fill:function (context){                    context.save();                    this.createPath(context);                    context.fillStyle = this.fillStyle;                    context.fill();                    context.restore();                },                move:function(x,y){                    this.x = x;                    this.y = y;                }            }            //开始拖拽            function startDragging(loc){                saveDrawingSurface();                mousedown.x =loc.x;                mousedown.y = loc.y;            }            //保存绘图表面            function saveDrawingSurface(){                drawingSurfaceImageData = context.getImageData(0,0,canvas.width,canvas.height);            }            //恢复绘图表面            function restoreDrawingSurface(){                context.putImageData(drawingSurfaceImageData,0,0);            }            //重新定位canvas中的坐标            function windowToCanvas(x,y){                var bbox = canvas.getBoundingClientRect(); //得到canvas元素的宽高定位                return {                    x:x-bbox.left * (canvas.width/bbox.width),                    y:y-bbox.top * (canvas.height/bbox.height)                };            }            //绘制网格线            function drawGrid(color,stepX,stepY){                context.save();                context.shadowColor = undefined;                context.shadowBlur = 0;                context.shadowOffsetX = 0;                context.shadowOffsetY = 0;                context.strokeStyle = color;                context.lineWidth = 0.5;                for(var i =stepX+0.5;i<context.canvas.width;i+=stepX){                    context.beginPath();                    context.moveTo(i,0);                    context.lineTo(i,context.canvas.height);                    context.stroke();                };                for(var i=stepY+0.5;i<context.canvas.height;i+=stepY){                    context.beginPath();                    context.moveTo(0,i);                    context.lineTo(context.canvas.width,i);                    context.stroke();                }                context.restore();            }    </script></html>
0 0