原文鏈接:https://www.codeproject.com/articles/598955/coordinateplussystemplusinplushtml-pluscanvas-cpl
canvas中的坐標(biāo)系,用y軸向上增長(zhǎng)繪圖
在某些動(dòng)畫類型中,默認(rèn)坐標(biāo)系是不方便的窄赋,幸好哟冬,你可以使用轉(zhuǎn)型方式來改變它...
HTML5 Canvas中的坐標(biāo)系統(tǒng)以左上角為其原點(diǎn)(0, 0)。這個(gè)解決方案在屏幕圖形學(xué)領(lǐng)域并不新鮮(例如windows窗體和svg也是如此)忆绰。過去標(biāo)準(zhǔn)的CRT監(jiān)視器從上到下顯示圖像行浩峡,并且從左到右創(chuàng)建行中的圖像。因此错敢,定位原點(diǎn)(0翰灾,0)在左上角是直觀的,它使創(chuàng)建硬件和軟件處理圖形更容易稚茅。
不幸的是有些時(shí)候纸淮,canvas中的默認(rèn)坐標(biāo)系統(tǒng)是有點(diǎn)不切實(shí)際的。比如你想創(chuàng)建彈丸運(yùn)動(dòng)動(dòng)畫亚享,對(duì)于上升的彈丸咽块,y坐標(biāo)是上升的這看起來是很自然的,但是這會(huì)導(dǎo)致一個(gè)很奇怪的效果:
您可以通過修改傳遞給繪圖方法的y值來解決這個(gè)問題:
contexnt.fillRect(x, offsetY - y, size, size);
對(duì)于y=0欺税,彈丸將被放置在由offsetY決定的位置(將offsetY設(shè)置為canvas的高度侈沪,以使y=0是畫布的最底部)飒货。 y的值愈大,彈跳將越會(huì)高峭竣,但是問題是你的代碼中將會(huì)有幾百個(gè)地方使用y坐標(biāo),如果你有一次忘記使用offsetY晃虫,那么整個(gè)圖像可能被破壞皆撩。
幸運(yùn)的是,canvas允許你使用變換來改變坐標(biāo)系統(tǒng)哲银。有兩種轉(zhuǎn)換方法對(duì)我們很有用:translate(x, y)和scale(x, y)扛吞。前者允許我們將原點(diǎn)移動(dòng)到任何位置,后者用于改變繪制對(duì)象的大小荆责,但是它也可以用來反轉(zhuǎn)坐標(biāo)滥比。
單次執(zhí)行以下代碼將坐標(biāo)系原點(diǎn)移動(dòng)到點(diǎn)(0, offsetY),并建立y軸值隨著朝向屏幕頂部的增加:
context.translate(0, offsetY);
context.scale(1, -1);
但是這里有個(gè)catch:提供-1作為scale的第二個(gè)參數(shù)的結(jié)果是整個(gè)圖像是為倒置y坐標(biāo)創(chuàng)建的做院。這也適用于文本(調(diào)用fillText將呈現(xiàn)字母上下顛倒)盲泛。因此,在寫任何文本之前键耕,您必須恢復(fù)默認(rèn)的y軸配置寺滚。因?yàn)槭謩?dòng)恢復(fù)畫布狀態(tài)是笨挫的,方法save()和restore()屈雄,這兩個(gè)方法分別用于在堆棧上保存畫布狀態(tài)和從畫布狀態(tài)堆棧中恢復(fù)狀態(tài)村视。建議在變換之前使用保存save方法。canvas的狀態(tài)不僅包括變換酒奶,還包括一些如填充樣式或者線寬之類的值...
context.save();
context.fillStyle = 'red';
context.scale(2, 2);
context.fillRect(0, 0, 10, 10);
context.restore();
context.fillRect(0, 0, 10, 10);
以上代碼繪制了2個(gè)正方形:
第一個(gè)正方形是紅色的且使用2倍刻度繪制蚁孔,第二個(gè)正方形使用默認(rèn)畫布設(shè)置(顏色黑色和1倍刻度)。這發(fā)生是因?yàn)樵趯?duì)比例和顏色進(jìn)行任何改變之前惋嚎,畫布狀態(tài)被保存在堆棧上杠氢,之后再繪制第二個(gè)正方形之前被恢復(fù)了。