獨的一個canvas標記只是在頁面中定義了一塊矩形區(qū)域,并無特別之處。開發(fā)人員只有配合使用javascript腳本,才能夠完成各種圖形、線條以及復(fù)雜的圖形變換操作。與基于SVG實現(xiàn)同樣繪圖效果來比較,canvas繪圖是一種像素級別的位圖繪圖技術(shù),而SVG則是一種矢量繪圖技術(shù)。
使用canvas和javascript繪制一個矩形,可能會涉及一個或多個方法,如下表所示:
(1)編寫代碼如下圖所示,在<body>標簽中加入以下代碼。
(2)在瀏覽器中打開文件,預(yù)覽效果圖如下所示,可以看到網(wǎng)頁中,在一個藍色邊框中顯示了一個藍色長方形。
小提示:上面代碼中,首先定義一個畫布對象,其id名稱為myCanvas,其高度和寬度為500像素,并定義了畫布邊框顯示樣式。在javascript代碼中,首先獲取畫布對象,然后使用getcontext獲取當前2D的上下文對象。并使用fillrect繪制一個矩形。其中涉及一個fillstyle屬性,fillstyle用于設(shè)置填充的顏色、透明度等。如果設(shè)置為“rgb(200,0,0)”,則表示一個顏色,不透明;如果設(shè)置為“rgba(0,0,200,0.5)”,則表示顏色為一個顏色,透明度為50%。
在閱讀本文前,你首先需要知道什么是 Fabric.js,還需要知道 Fabric.js 是如何創(chuàng)建矩形的。
如果你還沒滿足上面2個條件,推薦閱讀 《Fabric.js從入門到____》
我在 Fabric.js 使用 框選操作 創(chuàng)建矩形。
接下來的幾篇文章我會寫如何自由繪制 圓形、橢圓形、三角形、線段、折線、多邊形。
本文不做任何 CSS 相關(guān)的美化,只講解實現(xiàn)原理。
下圖是本文的要實現(xiàn)的效果。
使用 Fabric.js 這類框架,是要注意版本的。
本文所用版本: Fabric.js 4.6.0
用 “框選” 的方式生成矩形,其核心就2點:
鼠標點擊:canvas.on('mouse:down', fn)
鼠標抬起: canvas.on('mouse:up', fn)
理解了上面的核心點,接下來需要考慮的是鼠標框選的 方向 。
上面這4種情況會影響生成出來的矩形的 長、寬 和 位置。
生成矩形的代碼
new fabric.Rect({
top: 0, // 矩形左上角在y軸的位置
left: 0, // 矩形左上角在x軸的位置
width: 100, // 矩形的寬
height: 100, // 矩形的高
fill: 'transparent', // 填充色
stroke: '#000' // 邊框顏色
})
接下來逐一說說這4種操作帶來的影響。
這種情況是最好處理的。
此時 起始點 就是矩形的左上角,結(jié)束點 就是矩形的右下角。
起始點 的 x 和 y 坐標 都小于 結(jié)束點,( 起始點x < 結(jié)束點x;起始點y < 結(jié)束點y ) :
起始點x > 結(jié)束點x; 起始點y > 結(jié)束點y
起始點x < 結(jié)束點x; 起始點y > 結(jié)束點y
起始點x > 結(jié)束點x; 起始點y < 結(jié)束點y
分析完上面4種情況,最后總結(jié)出來這幾個參數(shù)的公式。
我將 起始點 命名為 downPoint,結(jié)束點 命名為 upPoint 。
矩形的幾個參數(shù)計算公式如下:
new fabric.Rect({
top: Math.min(downPoint.y, upPoint.y),
left: Math.min(downPoint.x, upPoint.x),
width: Math.abs(downPoint.x - upPoint.x),
height: Math.abs(downPoint.y - upPoint.y),
fill: 'transparent',
stroke: '#000'
})
Math.min:兩者之中取小值
Math.abs:返回絕對值
這兩個都是 JS 提供的方法,如果不理解的建議去百度一下。
我在這里貼出用 原生方式 實現(xiàn)的代碼和注釋。
如果你想知道在 Vue3 環(huán)境下如何實現(xiàn) Fabric.js 自由繪制矩形,可以在 代碼倉庫 里查找。
<!-- 工具欄 -->
<div class="toolbar">
<select onchange="typeChange(this.options[this.options.selectedIndex].value)">
<option value="default">默認(框選)</option>
<option value="rect">矩形</option>
</select>
</div>
<!-- 畫布 -->
<canvas id="canvas" width="800" height="800"></canvas>
<!-- 引入fabric.js -->
<script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/460/fabric.js"></script>
<script>
let canvas = null // 畫布對象
let currentType = 'default' // 當前操作模式(默認 || 創(chuàng)建矩形)
let downPoint = null // 按下鼠標時的坐標
let upPoint = null // 松開鼠標時的坐標
// 初始化畫板
function initCanvas() {
canvas = new fabric.Canvas('canvas')
canvas.on('mouse:down', canvasMouseDown) // 鼠標在畫布上按下
canvas.on('mouse:up', canvasMouseUp) // 鼠標在畫布上松開
}
// 畫布操作類型切換
function typeChange(opt) {
currentType = opt
switch(opt) {
case 'default': // 默認框選模式
canvas.selection = true // 允許框選
canvas.selectionColor = 'rgba(100, 100, 255, 0.3)' // 選框填充色:半透明的藍色
canvas.selectionBorderColor = 'rgba(255, 255, 255, 0.3)' // 選框邊框顏色:半透明灰色
canvas.skipTargetFind = false // 允許選中
break
case 'rect': // 創(chuàng)建矩形模式
canvas.selectionColor = 'transparent' // 選框填充色:透明
canvas.selectionBorderColor = 'rgba(0, 0, 0, 0.2)' // 選框邊框顏色:透明度很低的黑色(看上去是灰色)
canvas.skipTargetFind = true // 禁止選中
break
}
}
// 鼠標在畫布上按下
function canvasMouseDown(e) {
// 鼠標左鍵按下時,將當前坐標 賦值給 downPoint。{x: xxx, y: xxx} 的格式
downPoint = e.absolutePointer
}
// 鼠標在畫布上松開
function canvasMouseUp(e) {
// 繪制矩形的模式下,才執(zhí)行下面的代碼
if (currentType === 'rect') {
// 松開鼠標左鍵時,將當前坐標 賦值給 upPoint
upPoint = e.absolutePointer
// 調(diào)用 創(chuàng)建矩形 的方法
createRect()
}
}
// 創(chuàng)建矩形
function createRect() {
// 如果點擊和松開鼠標,都是在同一個坐標點,不會生成矩形
if (JSON.stringify(downPoint) === JSON.stringify(upPoint)) {
return
}
// 創(chuàng)建矩形
// 矩形參數(shù)計算(前面總結(jié)的4條公式)
let top = Math.min(downPoint.y, upPoint.y)
let left = Math.min(downPoint.x, upPoint.x)
let width = Math.abs(downPoint.x - upPoint.x)
let height = Math.abs(downPoint.y - upPoint.y)
// 矩形對象
const rect = new fabric.Rect({
top,
left,
width,
height,
fill: 'transparent', // 填充色:透明
stroke: '#000' // 邊框顏色:黑色
})
// 將矩形添加到畫布上
canvas.add(rect)
// 創(chuàng)建完矩形,清空 downPoint 和 upPoint。當然,你也可以不做這步。
downPoint = null
upPoint = null
}
// 頁面加載的生命周期,在此執(zhí)行 初始化畫布 的操作
window.onload = function() {
initCanvas()
}
</script>
最后別忘了 關(guān)注 點贊 收藏
1.段落標簽<p>
<style> p{margin:0px;} </style>
2.斜體標簽<em>
<em>斜體</em>
3.粗體標簽<strong>
<strong>加粗</strong>
4.<span>標簽
被用來組合文檔中的行內(nèi)元素。使用 <span> 來組合行內(nèi)元素,以便通過樣式來格式化它們。
例如:
<style> span{ color:blue; } </style>
這樣,<span>標簽包含的文本就變成了藍色的字體。
5.<q>標簽
作用:段文本引用
例如:
<p>最初知道莊子,是從一首詩<q>莊生曉夢迷蝴蝶。望帝春心托杜鵑。</q>開始的。雖然當時不知道是什么意思,只是覺得詩句挺特別。后來才明白這個典故出自是莊子的《逍遙游》,《逍遙游》代表了莊子思想的最高境界,是對世俗社會的功名利祿及自己的舍棄。</p> 在上面的例子中,“莊生曉夢迷蝴蝶。望帝春心托杜鵑。” 這是一句詩歌,出自晚唐詩人李商隱的《錦瑟》 。因為不是作者自己的文字,所以需要使用<q></q>實現(xiàn)引用。 注意要引用的文本不用加雙引號,瀏覽器會對q標簽自動添加雙引號。 這里用<q>標簽的真正關(guān)鍵點不是它的默認樣式雙引號(如果這樣我們不如自己在鍵盤上輸入雙引號就行了),而是它的語義:引用別人的話。 補充知識:語義化網(wǎng)頁結(jié)構(gòu)有助于搜索引擎的收錄。同一個效果可以用很多鐘方式實現(xiàn),但這只方便了瀏覽者,而搜索引擎不知道這里到底是什么內(nèi)容,這里如果你使用標簽,那么就告訴瀏覽器這里是引用的話。而且在手持設(shè)備或移動設(shè)備不能很好支持css的基礎(chǔ)上,瀏覽器會使用默認的效果,因而提供較好可讀性。
6.<blockquote>標簽
作用:長文本引用
例如:
<blockquote>明月出天山,蒼茫云海間。長風幾萬里,吹度玉門關(guān)。漢下白登道,胡窺青海灣。由來征戰(zhàn)地,不見有人還。 戍客望邊色,思歸多苦顏。高樓當此夜,嘆息未應(yīng)閑。</blockquote>
注意:瀏覽器對<blockquote>標簽的解析是縮進樣式
7.<br>標簽
怎么可以讓每一句詩詞后面加入一個折行呢?那就可以用到<br />標簽了,在需要加回車換行的地方加入<br />,<br />標簽作用相當于word文檔中的回車。
語法:
xhtml1.0寫法:
<br/>
html4.01寫法:
<br>
現(xiàn)在一般使用 xhtml1.0 的版本的寫法(其它標簽也是),這種版本比較規(guī)范。
與以前我們學過的標簽不一樣,<br />標簽是一個空標簽,沒有HTML內(nèi)容的標簽就是空標簽,空標簽只需要寫一個開始標簽,這樣的標簽有<br />、<hr />和<img />。
講到這里,你是不是有個疑問,想折行還不好說嘛,就像在 word 文件檔或記事本中,在想要折行的前面輸入回車不就行了嗎? 不好意思,在 html 中是忽略回車和空格的,你輸入的再多回車和空格也是顯示不出來的。
8.<hr>標簽
在信息展示時,有時會需要加一些用于分隔的橫線,這樣會使文章看起來整齊些。
語法:
html4.01版本
<hr>
xhtml1.0版本
<hr/>
注意:
9.<address>標簽
一般網(wǎng)頁中會有一些網(wǎng)站的聯(lián)系地址信息需要在網(wǎng)頁中展示出來,這些聯(lián)系地址信息如公司的地址就可以<address>標簽。也可以定義一個地址(比如電子郵件地址)、簽名或者文檔的作者身份。
語法:
<address>聯(lián)系地址信息</address>
如:
<address>文檔編寫:lilian 北京市西城區(qū)德外大街10號</address>
10.<code>標簽
在介紹語言技術(shù)的網(wǎng)站中,避免不了在網(wǎng)頁中顯示一些計算機專業(yè)的編程代碼,當代碼為一行代碼時,你就可以使用<code>標簽了,如下面例子:
<code>var i=i+300;</code>
注意:在文章中一般如果要插入多行代碼時不能使用<code>標簽了。
語法:
<code>代碼語言</code>
注:如果是多行代碼,可以使用<pre>標簽。
11.<pre>標簽
主要作用:預(yù)格式化的文本。被包圍在 pre 元素中的文本通常會保留空格和換行符。
語法:
<pre>語言代碼段</pre>
如下代碼:
<pre> var message="歡迎"; for(var i=1;i<=10;i++) { alert(message); } </pre>
效果如下:
注意:<pre> 標簽不只是為顯示計算機的源代碼時用的,在你需要在網(wǎng)頁中預(yù)顯示格式時都可以使用它,只是<pre>標簽的一個常見應(yīng)用就是用來展示計算機的源代碼。
12.<ul>標簽
ul-li是沒有前后順序的信息列表。
ul{ list-style:circle; }
ul{ list-style:none }
<ul> <li>信息</li> <li>信息</li> ...... </ul>
<ul> <li>精彩少年</li> <li>美麗突然出現(xiàn)</li> <li>觸動心靈的旋律</li> </ul>
13.<ol>標簽
ol-li是有前后順序的信息列表
<ol> <li>信息</li> <li>信息</li> ...... </ol>
<ol> <li>前端開發(fā)面試心法 </li> <li>零基礎(chǔ)學習html</li> <li>JavaScript全攻略</li> </ol>
<ol>在網(wǎng)頁中顯示的默認樣式一般為:每項<li>前都自帶一個序號,序號默認從1開始。
14.<div>標簽
15.<table>標簽
1)屬性:border
作用:規(guī)定表格邊框的寬度
2)屬性:cellpadding
作用:單元格中的文本與單元格邊框的間距
3)屬性:cellspacing
作用:單元格之間的間距
table、tbody、tr、th、td
1、<table>…</table>:整個表格以<table>標記開始、</table>標記結(jié)束。
2、<tbody>…</tbody>:當表格內(nèi)容非常多時,表格會下載一點顯示一點,但如果加上<tbody>標簽后,這個表格就要等表格內(nèi)容全部下載完才會顯示。如右側(cè)代碼編輯器中的代碼。
3、<tr>…</tr>:表格的一行,所以有幾對tr 表格就有幾行。
4、<td>…</td>:表格的一個單元格,一行中包含幾對<td>...</td>,說明一行中就有幾列。
- 常用屬性: colspan:規(guī)定單元格可橫跨的列數(shù),值為數(shù)字 rowspan:規(guī)定單元格可橫跨的行數(shù),值為數(shù)字
5、<th>…</th>:表格的頭部的一個單元格,表格表頭。
6、表格中列的個數(shù),取決于一行中數(shù)據(jù)單元格的個數(shù)。
總結(jié):
16.<caption>標簽
表格還是需要添加一些標簽進行優(yōu)化,可以添加標題和摘要。
摘要的內(nèi)容是不會在瀏覽器中顯示出來的。它的作用是增加表格的可讀性(語義化),使搜索引擎更好的讀懂表格內(nèi)容,還可以使屏幕閱讀器更好的幫助特殊用戶讀取表格內(nèi)容。語法:
<table summary="表格簡介文本">
用以描述表格內(nèi)容,標題的顯示位置:表格上方。語法:
<table> <caption>標題文本</caption> <tr> <td>…</td> <td>…</td> … </tr> … </table>
17.<a>標簽
<a href="目標網(wǎng)址" title="鼠標滑過顯示的文本">鏈接顯示的文本</a>
例如:
<a title="點擊進入慕課網(wǎng)">click here!</a>
上面例子作用是單擊click here!文字,網(wǎng)頁鏈接跳轉(zhuǎn)到http://www.imooc.com這個網(wǎng)頁。
<a href="目標網(wǎng)址" target="_blank">click here!</a>
<a>標簽還有一個作用是可以鏈接Email地址,使用mailto能讓訪問者便捷向網(wǎng)站管理者發(fā)送電子郵件。
注意:如果mailto后面同時有多個參數(shù)的話,第一個參數(shù)必須以“?”開頭,后面的參數(shù)每一個都以“&”分隔。引號只有一對!
例子: <a href="mailto:yy@qq.com? cc=xx@qq.com & bcc=aa@qq.com & subject=郵件主題 & body=郵件內(nèi)容">
那么: 1)A知道自己發(fā)送郵件給了B1、B2、B3,并且抄送給了C1、C2、C3,密送給了D1、D2、D3。 2)B1知道這封是A發(fā)送給B1、B2、B3的郵件,并且抄送給了C1、C2、C3,但不知道密送給了D1、D2、D3。 3)C1知道這封是A發(fā)送給B1、B2、B3的郵件,并且抄送給了C1、C2、C3,但不知道密送給了D1、D2、D3。 4)D1知道這封是A發(fā)送給B1、B2、B3的郵件,并且抄送給了C1、C2、C3,而且密送給了自己,但不知道密送給了D2、D3。 5)郵箱地址 mailto: <a href="mailto:qiujie@staff.weibo.com">發(fā)送</a> 6)抄送地址 cc: <a href="mailto:qiujie@staff.weibo.com?cc=zz@sina.com">發(fā)送</a> 7)密件抄送地址 用分號分隔: <a href="mailto:qiujie@staff.weibo.com?bcc=zz@sina.com">發(fā)送</a> 8)多個收件人、抄送人、密送人 ; bcc: <a href="mailto:qiujie@staff.weibo.com;zz@sina.com">發(fā)送</a> 9)郵件主題 subject: <a href="mailto:qiujie@staff.weibo.com?subject=郵件主題">發(fā)送</a> 10)郵件內(nèi)容 body: <a href="mailto:qiujie@staff.weibo.com?body=郵件正文">發(fā)送</a> 例子: <a href="mailto:yy@imooc.com;10001@qq.com?cc=10002@qq.com&bbc=madanteng@qqhelp.com&subject=觀了不起的蓋茨比有感。&body=你好,對此評論有些想法。">對此影評有何感想,發(fā)送郵件給我</a>
18.<img>標簽
在網(wǎng)頁的制作中為使網(wǎng)頁炫麗美觀,肯定是缺少不了圖片,可以使用
標簽來插入圖片。
[站外圖片上傳中……(2)] <img src = "myimage.gif" alt = "My Image" title = "My Image" />
src:標識圖像的位置; alt:指定圖像的描述性文本,當圖像不可見時(下載不成功時),可看到該屬性指定的文本; title:提供在圖像可見時對圖像的描述(鼠標滑過圖片時顯示的文本); 圖像可以是GIF,PNG,JPEG格式的圖像文件。 路徑有兩種填寫方式:絕對路徑、相對路徑 相對路徑:相對于我們當前 html 文件的位置來寫路徑即可! ./表示當前目錄,../表示上一級目錄
19.<form>標簽
注意:
1、所有表單控件(文本框、文本域、按鈕、單選框、復(fù)選框等)都必須放在<form></form>標簽之間(否則用戶輸入的信息可提交不到服務(wù)器上哦!)。
2、method:post/get的區(qū)別這一部分內(nèi)容屬于后端程序員考慮的問題。
語法:
<form method="傳送方式" action="服務(wù)器文件">
<form> :<form>標簽是成對出現(xiàn)的,以<form>開始,以</form>結(jié)束。 action :瀏覽者輸入的數(shù)據(jù)被傳送到的地方,比如一個PHP頁面(save.php)。 method : 數(shù)據(jù)傳送的方式(get/post)。 <form method="post" action="save.php"> <label for="username">用戶名:</label> <input type="text" name="username" /> <label for="pass">密碼:</label> <input type="password" name="pass" /> </form>
20.<input>標簽
語法:
<form> <input type="text/password" name="名稱" value="文本" /> </form>
舉例: <form> 姓名: <input type="text" name="myName"/><br/> 密碼: <input type="password" name="pass"/> </form> value="xxx" 替換為 placeholder="xxx" 的體驗更好一些,placeholder屬性為 HTML 5 的新屬性。placeholder 屬性提供可描述輸入字段預(yù)期值的提示信息(hint)。該提示會在輸入字段為空時顯示,并會在字段獲得焦點時消失。
語法:
<input placeholder="text"/> 注釋:placeholder 屬性適用于以下的 <input> 類型:text, search, url, telephone, email 以及 password。
注意:同一組的單選按鈕,name 取值一定要一致,比如上同一個名稱“gender”,這樣同一組的單選按鈕才可以起到單選的作用!
type:
name:為文本框命名,以備后臺程序ASP 、PHP使用。
value:為文本輸入框設(shè)置默認值。(一般起到提示作用)
21.<textarea>標簽
語法:
<textarea rows="行數(shù)" cols="列數(shù)">文本</textarea>
舉例:
<form method="post" action="save.php"> <label>聯(lián)系我們</label> <textarea cols="50" rows="10" >在這里輸入內(nèi)容...</textarea> </form>
22.<select>標簽
語法:
<select> <option value="提交的值">顯示的值</option> ... </select> 設(shè)置selected="selected"屬性,則該選項就被默認選中。 selected="selected"
<select multiple="multiple"> 然后選擇時候按ctrl點鼠標選中
<option disabled="disabled">
把相關(guān)的選項組合在一起
屬性 label:給選項組命名
屬性 disabled:禁用該選項組
23.<label>標簽
<label for="控件id名稱">
注意:標簽的 for 屬性中的值應(yīng)當與相關(guān)控件的 id 屬性值一定要相同。
<form> <label for="male">男</label> <input type="radio" name="gender" id="male" /> <br /> <label for="female">女</label> <input type="radio" name="gender" id="female" /> <label for="email">輸入你的郵箱地址</label> <input type="email" id="email" placeholder="Enter email"> </form>
24.<map>標簽
使用 map 標簽可以給圖片某塊區(qū)域加超鏈接
使用方法:
1)為 map 標簽首先加上 id 屬性用來為 map 標簽定義一個唯一的名稱
2)為了保證兼容性再加上 name 屬性,屬性值與 id 的值相同
3)為 map 標簽所作用的圖片加上 usemap 屬性,屬性值為 #id 名稱
4)在 map 標簽內(nèi)嵌套 area 標簽來實現(xiàn)給指定區(qū)域加鏈接
<area shape="" coords="" href ="" alt="" /> shape 屬性:定義鏈接區(qū)域的形狀,常用值 rect、circle coords 屬性:確定區(qū)域的精確位置。填寫坐標即可,以父元素左上角為原點,可借助qq截圖來得到想要的坐標 href 屬性:填寫鏈接地址即可 alt 屬性:給鏈接加一些說明信息
例子:
<map id="img1" name="img1"> <area shape="rect" coords="184,33,391,258" href="http:www.baidu.com" alt="百度一下" target="_blank" /> <area shape="circle" coords="507,287,20" alt="私房庫我的博客" target="_blank" /> </map>
注意:
25.<iframe>標簽
創(chuàng)建包含另外一個文檔的內(nèi)聯(lián)框架(即行內(nèi)框架)
屬性:
值:1、0
作用:規(guī)定是否顯示框架周圍的邊框。
作用:定義 iframe 的寬度
作用:定義高度
作用:給 iframe 命名
值:yes、no、auto
作用:規(guī)定是否在 iframe 中顯示滾動條
作用:規(guī)定在 iframe 中顯示的文檔的 URL
可以是本地的 html 文件,也可以是遠程的 html 文件
標簽寫法
1)不允許寫結(jié)束標簽的元素
area,base,br,col,command,embed,hr,img,input,keygen,link,meta,paran,source,track,wbr。這些標簽都是單標簽例如:br 標簽,不可以這樣<br></br>,只能<br />這樣來關(guān)閉標簽。
2)可以省略結(jié)束標記的元素有:
li,dt,dd,p,rt,rp,optgroup,option,colgroup,thead,tbody,tfoot,tr,td,th。
3)可以省略全部標記的元素有
html,head,body,colgroup,tbody
例如:disabled,readonly,checked 等只寫屬性而不寫屬性值得時候當做 ture 不寫屬性表示 false
要求:屬性值不包含 空字符串,<,>,=, ‘
標簽嵌套探討
1.html 規(guī)定我們必須要嵌套著寫的標簽
例如:頁面頭部是嵌套在 head 標簽里面的,主體內(nèi)容都是嵌套在 body 標簽里面的表單的內(nèi)容是嵌套在 form 標簽里面的,dt、dd 是嵌套在 dl 標簽里面的,li 是嵌套到ul 標簽里面的,等等...
2.塊級元素可以嵌套內(nèi)聯(lián)元素,但是內(nèi)聯(lián)元素不能包含塊元素
<div> <span>我是一個 span 元素</span> </div> —— 對 <span> <div>div 元素</div> </span> —— 錯
3.內(nèi)聯(lián)元素可以嵌套內(nèi)聯(lián)元素
<a href="#"> <span></span> </a> —— 對
4.塊級元素與塊級元素嵌套注意點
<p><ol><li></li></ol></p> —— 錯 <p><div></div></p> —— 錯
喜歡前端的小伙伴們可以在評論區(qū)留言,尋找和小馮童鞋一樣熱愛前端的友人,讓我們一起玩轉(zhuǎn)前端的世界!
*請認真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。