2013-07-29 82 views
2

我正在使用以下代碼繪製正方形。我是新來的JavaScript。任何人都可以告訴我下面的代碼有什麼問題嗎?它不繪製一個確切的/正確的方形。正方形的邊長必須是x & y之間的長邊。我認爲有一些維度問題。請幫忙!使用畫布在javascript中繪製正方形

construct: function(pos,parent) { 
     obj=Object.create(parent); 
     obj.minx=obj.maxx=pos.x; 
     obj.miny=obj.maxy=pos.y; 
     if (fillColor!="inherit") 
     obj.fillStyle=fillColor; 
     if (strokeColor!="inherit") 
     obj.strokeStyle=strokeColor; 
     if (strokeThickness!="inherit") 
     obj.lineWidth=strokeThickness; 
     }, 
    draw: function(selected) { 
     ctx.beginPath(); 
     ctx.fillStyle=this.fillStyle; 
     ctx.strokeStyle=(selected) ? 
         "gray" : this.strokeStyle; 
     ctx.lineWidth=this.lineWidth; 

    ctx.rect(this.minx,this.miny,this.maxx,this.maxy); 

     ctx.fill(); 
     if (selected) { 
     ctx.moveTo(this.minx,this.miny); 
     ctx.lineTo(this.maxx,this.maxy); 
     ctx.moveTo(this.minx,this.maxy); 
     ctx.lineTo(this.maxx,this.miny); 
     } 
     ctx.stroke(); 
     }, 
    mousedown: function(event) { 
     downPos=event; 
     square.construct(downPos,drawObject[containingBox4point(downPos)]); 
     inDrag=true; 
     }, 
    mousemove: function(event) { 
     if (!inDrag) 
     { 
     drawPrevious(); 
     drawCursor(event,containingBox4point(event)); 
     return; 
     } 
     upPos=event; 
     if (upPos.x>downPos.x) { 
     obj.minx=downPos.x; 
     obj.maxx=upPos.x + Math.abs(obj.maxy - obj.miny); 
     } 
     else { 
     obj.minx=upPos.x; 
     obj.maxx=downPos.x + Math.abs(obj.maxy - obj.miny); 
     } 
     if (upPos.y>downPos.y) { 
     obj.miny=downPos.y; 
     obj.maxy=upPos.y + Math.abs(obj.maxx - obj.minx); 
     } 
     else { 
     obj.miny=upPos.y; 
     obj.maxy=downPos.y + Math.abs(obj.maxx - obj.minx); 
     } 
     drawPrevious(); 
     obj.draw(containingBox(obj)==(-1)); 
     drawCursor(event,containingBox4point(upPos)); 
     } 
+1

這將是一個有點容易採取刺傷,如果你與你的HTML和JS創建了一個小提琴手如此我們可以看到你的意思是不工作。 –

+0

我想使它像這樣工作:http://jsfiddle.net/AbdiasSoftware/kqW4X/ – user2559199

+0

我相信@Bubbafat是要求你用** YOUR ** html和js創建一個小提琴。 – dc5

回答

9

基於單選按鈕模式

enter image description hereenter image description here

我提供這樣的解釋,我恭敬地相信你的代碼已經熄滅當然有點:)

在畫布上繪圖矩形或正方形

簡要教程

此代碼使用jQuery,它可以消除不同Web瀏覽器之間的差異。

<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 

首先,讓畫布元素

// get a reference to the canvas element 

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

參考繪製(稱爲CTX)創建畫布背景:

// create a canvas context to draw stuff with 

var ctx=canvas.getContext("2d"); 

設置上下文有些款式

// set the context's fill and stroke styles 
ctx.fillStyle="skyblue"; 
ctx.strokeStyle="lightgray"; 
ctx.lineWidth=3; 

保存canva在網頁上的位置。

這將在稍後用於計算鼠標位置。

// get the canvas's position on the page 

var canvasOffset=$("#canvas").offset(); 
var offsetX=canvasOffset.left; 
var offsetY=canvasOffset.top; 

由於我們要拖拽,設置變量來保存阻力

// set up variables to hold the mouse starting X/Y 
// when the user drags the mouse 
var startX; 
var startY; 

的起始XY創建一個變量來表示,如果我們在拖動的中間。

// indicate whether the user is dragging the mouse 

var isDragging=false; 

創建一個變量來指示是否應該被描繪爲正方形或矩形:

// set up a variable to determine whether to draw a square or a rectangle 

var modeName="square"; 

這個代碼設定modeName變量當用戶點擊任一個「方形」或「矩形」無線電按鈕

如果用戶點擊了「矩形」單選按鈕,然後modeName將被設置爲「矩形」

如果用戶點擊了「方形」單選按鈕,則ñmodeName將被設置爲「廣場」

// use jQuery to set the modeName variable 

$('input[name=mode]').click(function() { 
    modeName=$('input[name=mode]:checked').val(); 
}); 

偵聽鼠標事件

使用jQuery來監聽當用戶按下/釋放mousebutton和移動鼠標。

    當用戶按下鼠標按鈕向下
  • handleMouseDown將被調用,
  • 當用戶釋放鼠標按鈕handleMouseUp將被調用,
  • 當用戶移動鼠標handleMouseMove將反覆被調用

偵聽鼠標事件:

// listen for mousedown, call handleMouseDown when it’s pressed 

$("#canvas").mousedown(function(e){handleMouseDown(e);}); 

// listen for mouseup, call handleMouseUp when it’s released 

$("#canvas").mouseup(function(e){handleMouseUp(e);}); 

// listen for mouse movements, call handleMouseMove when the mouse moves 

$("#canvas").mousemove(function(e){handleMouseMove(e);}); 

當用戶按下,釋放並移動鼠標拖動時處理!

當用戶按下鼠標向下時,handleMouseDown函數被調用:

  • 店鋪在STARTX和startY起始鼠標位置。
  • 將isDragging標誌設置爲true。

handleMouseDown:

// called when user presses the mouse button down 
// This is the start of a drag 

function handleMouseDown(e){ 

    // calculate the mouse position relative to the canvas 

    mouseX=parseInt(e.clientX-offsetX); 
    mouseY=parseInt(e.clientY-offsetY); 

    // store the starting mouse position 

    startX=mouseX; 
    startY=mouseY; 

    // set isDragging to indicate we’re starting a drag. 

    isDragging=true; 
} 

當用戶釋放鼠標按鈕時,handleMouseUp函數被調用

  • 清除isDragging標誌(拖動結束)

handleMouseUp :

// called when the user releases the mouse button, 

function handleMouseUp(e){ 

    // the drag is over, clear the isDragging flag 

    isDragging=false; 

} 

當用戶拖動時,handleMouseMove功能被一再呼籲:

  • 如果未設置isDragging標誌,只是退出。
  • 清除畫布以準備新定位的矩形/正方形。
  • 如果用戶想要一個矩形,請調用一個函數來繪製一個矩形。
  • 如果用戶想要一個正方形,請調用一個函數來繪製正方形。

handleMouseMove:

// called repeatedly when the user drags the mouse 

function handleMouseMove(e){ 

    // calculate the mouse position relative to the canvas 

    mouseX=parseInt(e.clientX-offsetX); 
    mouseY=parseInt(e.clientY-offsetY); 

    // if the user isn’t dragging, just exit 

    if(!isDragging){ return; } 

    // clear the canvas in preparation for drawing a modified square/rectangle 

    ctx.clearRect(0,0,canvas.width,canvas.height); 

    // this switch decided if the user selected a rectangle or square for drawing 

    switch(modeName){ 

     // the user clicked the rectangle radio button and modeName == 「rectangle」 

     case "rectangle": 

      // call a function that draws a rectangle 

      drawRectangle(mouseX,mouseY); 

      break; 

     // the user clicked the rectangle radio button and modeName == 「square」 

     case "square": 

      // call a function that draws a square 

      drawSquare(mouseX,mouseY); 

      break; 

     default: 
      break; 
    } 

} 

此函數繪製一個矩形從STARTX/startY到當前mouseX/mouseY的

function drawRectangle(mouseX,mouseY){ 
    var width=mouseX-startX; 
    var height=mouseY-startY; 
    ctx.beginPath(); 
    ctx.rect(startX,startY,width,height); 
    ctx.fill(); 
    ctx.stroke(); 
} 

此函數繪製一個正方形從STARTX/startY朝向當前鼠標X /鼠標Y

廣場的所有4邊將由以下項確定:mouseX - startX

由於方必須執行4個相等邊,拖動正方形時,它可能會出現「跳」

function drawSquare(mouseX,mouseY){ 
    var width=Math.abs(mouseX-startX)*(mouseX<startX?-1:1); 
    var height=Math.abs(width)*(mouseY<startY?-1:1); 
    ctx.beginPath(); 
    ctx.rect(startX,startY,width,height); 
    ctx.fill(); 
    ctx.stroke(); 
} 

這裏是代碼和一個小提琴:http://jsfiddle.net/m1erickson/myHDW/

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 

<style> 
    body{ background-color: ivory; padding:20px;} 
    #canvas{border:1px solid red;} 
    input{width:15px;} 
</style> 

<script> 
$(function(){ 

    var canvas=document.getElementById("canvas"); 
    var ctx=canvas.getContext("2d"); 

    var canvasOffset=$("#canvas").offset(); 
    var offsetX=canvasOffset.left; 
    var offsetY=canvasOffset.top; 

    var startX; 
    var startY; 
    var isDown=false; 

    ctx.fillStyle="skyblue"; 
    ctx.strokeStyle="lightgray"; 
    ctx.lineWidth=3; 

    var modeName="square"; 

    $('input[name=mode]').click(function() { 
     modeName=$('input[name=mode]:checked').val(); 
     console.log(modeName); 
    }); 


    function handleMouseDown(e){ 
     mouseX=parseInt(e.clientX-offsetX); 
     mouseY=parseInt(e.clientY-offsetY); 

     // Put your mousedown stuff here 
     startX=mouseX; 
     startY=mouseY; 
     isDown=true; 
    } 

    function handleMouseUp(e){ 
     mouseX=parseInt(e.clientX-offsetX); 
     mouseY=parseInt(e.clientY-offsetY); 
     $("#uplog").html("Up: "+ mouseX + "/" + mouseY); 

     // Put your mouseup stuff here 
     isDown=false; 
    } 

    function handleMouseMove(e){ 
     mouseX=parseInt(e.clientX-offsetX); 
     mouseY=parseInt(e.clientY-offsetY); 

     // Put your mousemove stuff here 
     if(!isDown){return;} 

     ctx.clearRect(0,0,canvas.width,canvas.height); 

     switch(modeName){ 
      case "rectangle": 
       drawRectangle(mouseX,mouseY); 
       break; 
      case "square": 
       drawSquare(mouseX,mouseY); 
       break; 
      default: 
       break; 
     } 

    } 

    function drawRectangle(mouseX,mouseY){ 
     var width=mouseX-startX; 
     var height=mouseY-startY; 
     ctx.beginPath(); 
     ctx.rect(startX,startY,width,height); 
     ctx.fill(); 
     ctx.stroke(); 
    } 

    function drawSquare(mouseX,mouseY){ 
     var width=Math.abs(mouseX-startX)*(mouseX<startX?-1:1); 
     var height=Math.abs(width)*(mouseY<startY?-1:1); 
     ctx.beginPath(); 
     ctx.rect(startX,startY,width,height); 
     ctx.fill(); 
     ctx.stroke(); 
    } 

    $("#canvas").mousedown(function(e){handleMouseDown(e);}); 
    $("#canvas").mousemove(function(e){handleMouseMove(e);}); 
    $("#canvas").mouseup(function(e){handleMouseUp(e);}); 


}); // end $(function(){}); 
</script> 

</head> 

<body> 
    <p>Note: the square's side length is determined</p> 
    <p>by mouseX minus startingX.</p> 
    <p>As a result, the square may "jump" as you</p> 
    <p>move left or above the starting point.</p> 
    <canvas id="canvas" width=300 height=300></canvas><br> 

    <input type="radio" id="rect" name="mode" value="rectangle" /> 
    <label for="rect">Rectangle</label> 
    <input type="radio" id="sqr" name="mode" value="square" checked="checked" /> 
    <label for="sqr">Square</label> 

</body> 
</html> 

[加成:有更多的Math.abs(mouseX-startX)和Math.abs(mouseY-startY)]長方形

這個替代drawSquare()將計算

function drawSquare(mouseX,mouseY){ 
     var lengthX=Math.abs(mouseX-startX); 
     var lengthY=Math.abs(mouseY-startY); 
     if(lengthX>lengthY){ 
      var width=lengthX*(mouseX<startX?-1:1); 
      var height=lengthX*(mouseY<startY?-1:1); 
     }else{ 
      var width=lengthY*(mouseX<startX?-1:1); 
      var height=lengthY*(mouseY<startY?-1:1); 
     } 
     ctx.beginPath(); 
     ctx.rect(startX,startY,width,height); 
     ctx.fill(); 
     ctx.stroke(); 
    } 
+1

+1(這是他們允許的!)進行廣泛和深入的解釋。 – K3N

+0

@markE非常感謝你的幫助。我試圖將上面的代碼與我的代碼整合,但是它的繪製矩形。你可以根據條件(從早期的解決方案)建議一些東西:Math.abs(obj.maxx-obj.minx)== Math.abs(obj.maxy-obj.miny)如何選擇maxx和maxy之間的較長時間,並相應地使用它作爲ctx.rect。 – user2559199

+0

我已經在上面的答案中添加了drawSquare(),它可以選擇長方形邊長度的x-drag和y-drag。 – markE

2

既然不能添加評論,我想補充的mathemtical額外的信息:X-阻力和y拖動和使用計算爲正方形的4個邊的長度越長從「markE」algorythm繪製廣場的一部分。

如果你使用:

var lengthX=Math.abs(mouseX-startX); 
var lengthY=Math.abs(mouseY-startY); 
if(lengthX<lengthY){ //changed this part 
    var width=lengthX*(mouseX<startX?-1:1); 
    var height=lengthX*(mouseY<startY?-1:1); 
} 
else{ 
    var width=lengthY*(mouseX<startX?-1:1); 
    var height=lengthY*(mouseY<startY?-1:1); 
} 

您可以刪除這個廣場跳躍和獲得更多的MS油漆樣的行動。

0

Thsis簡單的Javascript,使廣場

<!DOCTYPE html> 
<html> 
<body> 

<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"> 
Your browser does not support the HTML5 canvas tag.</canvas> 

<script> 

var c = document.getElementById("myCanvas"); 
var ctx = c.getContext("2d"); 
ctx.rect(20, 20, 150, 100); 
ctx.stroke(); 

</script> 

</body> 
</html> 

更多設計請點擊這裏:How to Create a Centered Square Crop