2016-08-03 104 views
0

我想創建一個簡單的畫布網格,它將適合玩家的當前縮放級別,但也適用於某個畫布高度/寬度成比例的屏幕限制。以下是我走到這一步:畫布網格在不同的縮放級別變得模糊

JS:

var bw = window.innerWidth/2; //canvas size before padding 
var bh = window.innerHeight/1.3; //canvas size before padding 
//padding around grid, h and w 
var pW = 30; 
var pH = 2; 
var lLimit = 0; //9 line limit for both height and width to create 8x8 

//size of canvas - it will consist the padding around the grid from all sides + the grid itself. it's a total sum 
var cw = bw + pW; 
var ch = bh + pH; 

var canvas = $('<canvas/>').attr({width: cw, height: ch}).appendTo('body'); 

var context = canvas.get(0).getContext("2d"); 

function drawBoard(){ 

    for (var x = 0; lLimit <= 8; x += bw/8) { //handling the height grid 
     context.moveTo(x, 0); 
     context.lineTo(x, bh); 
     lLimit++; 
    } 

    for (var x = 0; lLimit <= 17; x += bh/8) { //handling the width grid 
     context.moveTo(0, x); //begin the line at this cord 
     context.lineTo(bw, x); //end the line at this cord 
     lLimit++; 
    } 
    //context.lineWidth = 0.5; what should I put here? 
    context.strokeStyle = "black"; 
    context.stroke(); 
} 

drawBoard(); 

現在,我終於成功了製作畫布是在每個屏幕分辨率縮放級別相同的比例水平。這是我想要實現的一部分。我也嘗試實現細線,在所有不同的縮放級別看起來都是一樣的,當然也是爲了消除模糊。現在線條的厚度 根據縮放級別而變化,並且有時模糊。

這裏的jsfiddle(雖然的jsfiddle窗口本身很小,所以你會發現幾乎沒有區別):

https://jsfiddle.net/wL60jo5n/

幫助將不勝感激。

+0

當你說縮放級別,你的意思是縮放內置到大多數瀏覽器(使用控制+ mwheel上/下)? –

+0

是的。 window.innerWidth會在頁面加載時考慮用戶的當前縮放級別。 – RunningFromShia

+0

我嘗試實現的網格系統的實例:http://slither.io/無論您進入網頁的縮放級別如何,或者即使在遊戲過程中放大和縮小,網格系統看起來都一樣。 – RunningFromShia

回答

0

問題是,你正在使用十進制值來繪製。您的drawBoard()循環使用分數中的畫布寬度和位置都會增加。畫布是位圖表面,而不是矢量圖。設置畫布的寬度和高度時,可以設置存儲在內存中的實際像素數。該值不能是小數(瀏覽器可能只是修整小數部分)。當您嘗試繪製小數位時,畫布將使用像素插值來避免混疊,因此偶爾會出現模糊。

看到一個版本,我之前繪製圓xhttps://jsfiddle.net/hts7yybm/

嘗試四捨五入的值在繪製之前,而不是在您的實際邏輯。這樣,由於算法不斷增加值,不精確度將不會疊加。

function drawBoard(){ 
    for (var x = 0; lLimit <= 8; x += bw/8) { 
    var roundedX = Math.round(x); 
    context.moveTo(roundedX, 0); 
    context.lineTo(roundedX, bh); 
    lLimit++; 
    } 

    for (var x = 0; lLimit <= 17; x += bh/8) { 
    var roundedX = Math.round(x); 
    context.moveTo(0, roundedX); 
    context.lineTo(bw, roundedX); 
    lLimit++; 
    } 
    context.lineWidth = 1; // never use decimals 
    context.strokeStyle = "black"; 
    context.stroke(); 
} 

編輯:我敢肯定所有的瀏覽器表現得好像畫布是一個img元素,所以沒有辦法防止混疊當用戶與他們的瀏覽器的縮放功能放大,比前綴其他CSS。即使如此,我不確定瀏覽器的縮放功能是否考慮到了這一點。

canvas { 
    image-rendering: -moz-crisp-edges; 
    image-rendering: -o-crisp-edges; 
    image-rendering: -webkit-optimize-contrast; 
    image-rendering: crisp-edges; 
    -ms-interpolation-mode: nearest-neighbor; 
} 

此外,請確保畫布沒有任何CSS設置尺寸。這隻在繪製完成後拉伸圖像,而不是增加繪圖表面。如果你想通過給它100%的寬度和高度填充一個塊,那麼你需要一些JS來計算CSS給定的高度和寬度,並基於此設置畫布寬度和高度屬性的值。然後,您可以在畫布繪圖代碼中自行實現縮放功能,但根據您所做的操作,這可能是矯枉過正的。

+0

我應用了你所做的,但沒有奏效。將縮放級別放在200%以上,然後刷新頁面。然後把它放在300%並刷新。您會注意到每個縮放級別的變化;它變得更厚或更薄。測試應該在普通的HTML窗口上執行,而不是jsFiddle,因爲差異不明顯。 – RunningFromShia

+0

我用新的信息編輯了答案。 –

0

爲防止模糊,在設置canvas元素的尺寸(當然,在後續繪圖期間考慮該尺寸時),應該考慮window.devicePixelRatio

widthheightcanvas元素的屬性應該包含比例高於相同名稱的CSS屬性值的值。這可以表示爲例如作爲以下功能:

function setCanvasSize(canvas, width, height) { 
    var ratio = window.devicePixelRatio, 
     style = canvas.style; 

    style.width = '' + (width/ratio) + 'px'; 
    style.height = '' + (height/ratio) + 'px'; 

    canvas.width = width; 
    canvas.height = height; 
}