溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

HTML中如何實(shí)現(xiàn)一個canvas智繪畫板

發(fā)布時間:2021-05-20 11:47:06 來源:億速云 閱讀:275 作者:小新 欄目:web開發(fā)

這篇文章主要介紹了HTML中如何實(shí)現(xiàn)一個canvas智繪畫板,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

 一、項(xiàng)目介紹

名稱:智繪畫板

技術(shù)棧:HTML5,CSS3,JavaScript,移動端

功能描述:

  • 支持PC端和移動端在線繪畫功能

  • 實(shí)現(xiàn)任意選擇畫筆顏色、調(diào)整畫筆粗細(xì)以及橡皮檫擦除等繪畫功能

  • 實(shí)現(xiàn)在線畫板的本地保存功能

  • 支持撤銷和返回操作

  • 自定義背景顏色

 二、項(xiàng)目效果展示

項(xiàng)目地址 預(yù)覽地址

預(yù)覽圖

PC端的預(yù)覽圖:

HTML中如何實(shí)現(xiàn)一個canvas智繪畫板

移動端的預(yù)覽圖:

HTML中如何實(shí)現(xiàn)一個canvas智繪畫板

看完上面的預(yù)覽圖和體驗(yàn)過 智繪畫板 覺得還可以的,記得點(diǎn)個贊哦,不管你是否十分激動,反正我是挺激動的,畢竟自己實(shí)現(xiàn)出現(xiàn)的項(xiàng)目效果,挺自豪的,說了一堆廢話,下面就可以動起手來敲代碼,實(shí)現(xiàn)自己想要的效果?。?!

注:下面實(shí)現(xiàn)項(xiàng)目效果主要是關(guān)于JavaScript方面的,下面僅僅是提供 實(shí)現(xiàn)思路的代碼 , 并非全部代碼 。

三、一步步實(shí)現(xiàn)項(xiàng)目效果

(一)分析頁面

通過 用例圖 ,我們知道用戶進(jìn)入我們這個網(wǎng)站有哪些功能?

用戶可以進(jìn)行的操作:

  • 畫畫

  • 改變畫筆的粗細(xì)

  • 切換畫筆的顏色

  • 使用橡皮檫擦除不想要的部分

  • 清空畫板

  • 將自己畫的東西保存成圖片

  • 進(jìn)行撤銷和重做操作

  • 切換畫板背景顏色

  • 兼容移動端(支持觸摸)

(二)進(jìn)行HTML布局

我書寫html的同時,引入了css文件和js文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>智繪畫板</title>
    <link rel="shortcut icon" href="./image/favicon.png" type="image/x-icon">
    <link rel="stylesheet" href="./css/style.css">
</head>
<body>
    <canvas id="canvas"></canvas>
    <div class="bg-btn"></div>
    <div class="color-group" id="bgGroup">
        <h4>選擇背景顏色:</h4>
        <ul class="clearfix">
            <li class="bgcolor-item" style="background-color: blue;"></li>
            <li class="bgcolor-item" style="background-color: black;"></li>
            <li class="bgcolor-item" style="background-color: #FF3333;"></li>
            <li class="bgcolor-item" style="background-color: #0066FF;"></li>
            <li class="bgcolor-item" style="background-color: #FFFF33;"></li>
            <li class="bgcolor-item" style="background-color: #33CC66;"></li>
            <li class="bgcolor-item" style="background-color: gray;"></li>
            <li class="bgcolor-item" style="background-color: #F34334;"></li>
            <li class="bgcolor-item" style="background-color: #fff;box-shadow: 0 1px 2px 0 rgba(32,33,36,0.28);"></li>
            <li class="bgcolor-item" style="background-color: #9B27AC;"></li>
            <li class="bgcolor-item" style="background-color: #4CB050;"></li>
            <li class="bgcolor-item" style="background-color: #029688;"></li>
        </ul>
        <i class="closeBtn"></i>
    </div>
    <div class="tools">
        <div class="container">
            <button class="save"  id="save" title="保存"></button>
            <button class="brush active" id="brush" title="畫筆"></button>
            <button class="eraser" id="eraser" title="橡皮擦"></button>
            <button class="clear" id="clear" title="清屏"></button>
            <button class="undo"  id="undo" title="撤銷"></button>
            <button class="redo"  id="redo" title="再做"></button>
        </div>
    </div>
    <div class="pen-detail" id="penDetail">
        <i class="closeBtn"></i>
        <p>筆大小</p>
        <span class="circle-box"><i id="thickness"></i></span> <input type="range" id="range1" min="1" max="10" value="1">
        <p>筆顏色</p>
        <ul class="pen-color clearfix">
            <li class="color-item active" style="background-color: black;"></li>
            <li class="color-item" style="background-color: #FF3333;"></li>
            <li class="color-item" style="background-color: #99CC00;"></li>
            <li class="color-item" style="background-color: #0066FF;"></li>
            <li class="color-item" style="background-color: #FFFF33;"></li>
            <li class="color-item" style="background-color: #33CC66;"></li>
        </ul>
        <p>不透明度</p>
        <i class="showOpacity"></i> <input type="range" id="range2" min="1" max="10" value="1">
    </div>
    <script src="./js/main.js"></script>
</body>
</html>

(三)用CSS美化界面

css代碼可以根據(jù)個人習(xí)慣進(jìn)行美化界面,所以這里就不寫css的代碼了,大家可以直接看 項(xiàng)目代碼 或者從開發(fā)者工具中審查元素觀看。如果有問題可以私聊我,我覺得問題不大。

(四)使用JS實(shí)現(xiàn)項(xiàng)目的具體功能

1.準(zhǔn)備工作

首先,準(zhǔn)備個容器,也就是畫板了,前面的html已經(jīng)書寫好這個容器,這里純屬是廢話。

<canvas id="canvas"></canvas>

然后初始化js

let canvas = document.getElementById('canvas');
let context = canvas.getContext('2d');

我打算把畫板做成全屏的,所以接下來設(shè)置一下 canvas 的寬高

let pageWidth = document.documentElement.clientWidth;
let pageHeight = document.documentElement.clientHeight;

canvas.width = pageWidth;
canvas.height = pageHeight;

由于部分IE不支持 canvas ,如果要兼容IE,我們可以創(chuàng)建一個 canvas ,然后使用 excanvas 初始化,針對IE加上exCanvas.js,這里我們明確不考慮IE。

但是我在電腦上對瀏覽器的窗口進(jìn)行改變,畫板不會自適應(yīng)的放縮。解決辦法:

// 記得要執(zhí)行autoSetSize這個函數(shù)哦
function autoSetSize(){
    canvasSetSize();
    // 當(dāng)執(zhí)行這個函數(shù)的時候,會先設(shè)置canvas的寬高
    function canvasSetSize(){
        let pageWidth = document.documentElement.clientWidth;
        let pageHeight = document.documentElement.clientHeight;
        
        canvas.width = pageWidth;
        canvas.height = pageHeight;
    }
    // 在窗口大小改變之后,就會觸發(fā)resize事件,重新設(shè)置canvas的寬高
    window.onresize = function(){
        canvasSetSize();
    }
}

2.實(shí)現(xiàn)畫畫的功能

實(shí)現(xiàn)思路:監(jiān)聽鼠標(biāo)事件, 用 drawLine() 方法把記錄的數(shù)據(jù)畫出來。

  • 初始化當(dāng)前畫板的畫筆狀態(tài), painting = false 。

  • 當(dāng)鼠標(biāo)按下時( mousedown ),把 painting 設(shè)為 true ,表示正在畫,鼠標(biāo)沒松開。把鼠標(biāo)點(diǎn)記錄下來。

  • 當(dāng)按下鼠標(biāo)的時候,鼠標(biāo)移動( mousemove )就 把點(diǎn)記錄 下來并畫出來。 如果鼠標(biāo)移動過快,瀏覽器跟不上繪畫速度,點(diǎn)與點(diǎn)之間會出現(xiàn)間隙,所以我們需要將畫出的點(diǎn)用線連起來( lineTo() )。

  • 鼠標(biāo)松開的時候( mouseup ),把 painting 設(shè)為 false 。

注: drawCircle 這個方法其實(shí)可以不用書寫,這個只是為了讓大家能夠理解開始點(diǎn)擊的位置在哪里?

function listenToUser() {
    // 定義一個變量初始化畫筆狀態(tài)
    let painting = false;
    // 記錄畫筆最后一次的位置
    let lastPoint = {x: undefined, y: undefined};

    // 鼠標(biāo)按下事件
    canvas.onmousedown = function(e){
        painting = true;
        let x = e.clientX;
        let y = e.clientY;
        lastPoint = {'x':x,'y':y};
        drawCircle(x,y,5);
    }

    // 鼠標(biāo)移動事件
    canvas.onmousemove = function(e){
        if(painting){
            let x = e.clientX;
            let y = e.clientY;
            let newPoint = {'x':x,'y':y};
            drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y);
            lastPoint = newPoint;
        }
    }

    // 鼠標(biāo)松開事件
    canvas.onmouseup = function(){
        painting = false;
    }
}

// 畫點(diǎn)函數(shù)
function drawCircle(x,y,radius){
    // 新建一條路徑,生成之后,圖形繪制命令被指向到路徑上生成路徑。
    context.beginPath();
    // 畫一個以(x,y)為圓心的以radius為半徑的圓?。▓A),
    // 從startAngle開始到endAngle結(jié)束,按照anticlockwise給定的方向(默認(rèn)為順時針)來生成。
    context.arc(x,y,radius,0,Math.PI*2);
    // 通過填充路徑的內(nèi)容區(qū)域生成實(shí)心的圖形
    context.fill();
    // 閉合路徑之后圖形繪制命令又重新指向到上下文中。
    context.closePath();
}

function drawLine(x1,y1,x2,y2){
    // 設(shè)置線條寬度
    context.lineWidth = 10;
    // 設(shè)置線條末端樣式。
    context.lineCap = "round";
    // 設(shè)定線條與線條間接合處的樣式
    context.lineJoin = "round";
    // moveTo(x,y)將筆觸移動到指定的坐標(biāo)x以及y上
    context.moveTo(x1,y1);
    // lineTo(x, y) 繪制一條從當(dāng)前位置到指定x以及y位置的直線
    context.lineTo(x2,y2);
    // 通過線條來繪制圖形輪廓
    context.stroke();
    context.closePath();
}

3.實(shí)現(xiàn)橡皮擦功能

實(shí)現(xiàn)思路:

  1. 獲取橡皮擦元素

  2. 設(shè)置橡皮擦初始狀態(tài), eraserEnabled = false 。

  3. 監(jiān)聽橡皮擦 click 事件,點(diǎn)擊橡皮擦,改變橡皮擦狀態(tài), eraserEnabled = true ,并且切換class,實(shí)現(xiàn) 被激活 的效果。

  4. eraserEnabledtrue 時,移動鼠標(biāo)用 context.clearRect() 實(shí)現(xiàn)了 橡皮檫。

但是我發(fā)現(xiàn)canvas的API中,可以清除像素的就是clearRect方法,但是clearRect方法的清除區(qū)域矩形,畢竟大部分人的習(xí)慣中的橡皮擦都是圓形的,所以就引入了剪輯區(qū)域這個強(qiáng)大的功能,也就是clip方法。下面的代碼是使用 context.clearRect() 實(shí)現(xiàn)了 橡皮檫。請看踩坑部分,了解如何更好的實(shí)現(xiàn)橡皮檫。

let eraser = document.getElementById("eraser");
let eraserEnabled = false;

// 記得要執(zhí)行l(wèi)istenToUser這個函數(shù)哦
function listenToUser() {
   	// ... 代表省略了之前寫的代碼
    // ...

    // 鼠標(biāo)按下事件
    canvas.onmousedown = function(e){
        // ...
        if(eraserEnabled){//要使用eraser
            context.clearRect(x-5,y-5,10,10)
        }else{
            lastPoint = {'x':x,'y':y}
        }
    }

    // 鼠標(biāo)移動事件
    canvas.onmousemove = function(e){
        let x = e.clientX;
        let y = e.clientY;
        if(!painting){return}
        if(eraserEnabled){
            context.clearRect(x-5,y-5,10,10);
        }else{
            var newPoint = {'x':x,'y':y};
            drawLine(lastPoint.x, lastPoint.y,newPoint.x, newPoint.y);
            lastPoint = newPoint;
        }  
    }

    // ...
}


// 點(diǎn)擊橡皮檫
eraser.onclick = function(){
    eraserEnabled = true;
    eraser.classList.add('active');
    brush.classList.remove('active');
}

4.實(shí)現(xiàn)清屏功能

實(shí)現(xiàn)思路:

獲取元素節(jié)點(diǎn)。

點(diǎn)擊清空按鈕清空canvas畫布。

let reSetCanvas = document.getElementById("clear");

// 實(shí)現(xiàn)清屏
reSetCanvas.onclick = function(){
    ctx.clearRect(0,0,canvas.width,canvas.height);
    setCanvasBg('white');
}

// 重新設(shè)置canvas背景顏色
function setCanvasBg(color) {
    ctx.fillStyle = color;
    ctx.fillRect(0, 0, canvas.width, canvas.height);
}

5.實(shí)現(xiàn)保存成圖片功能

實(shí)現(xiàn)思路:

  • 獲取canvas.toDateURL

  • 在頁面里創(chuàng)建并插入一個a標(biāo)簽

  • a標(biāo)簽href等于canvas.toDateURL,并添加download屬性

  • 點(diǎn)擊保存按鈕,a標(biāo)簽觸發(fā)click事件

let save = document.getElementById("save");

// 下載圖片
save.onclick = function(){
    let imgUrl = canvas.toDataURL('image/png');
    let saveA = document.createElement('a');
    document.body.appendChild(saveA);
    saveA.href = imgUrl;
    saveA.download = 'mypic'+(new Date).getTime();
    saveA.target = '_blank';
    saveA.click();
}

6.實(shí)現(xiàn)改變背景顏色的功能

實(shí)現(xiàn)思路:

  1. 獲取相應(yīng)的元素節(jié)點(diǎn)。

  2. 給每一個class為bgcolor-item的標(biāo)簽添加點(diǎn)擊事件,當(dāng)點(diǎn)擊事件觸發(fā)時,改變背景顏色。

  3. 點(diǎn)擊設(shè)置背景顏色的div之外的地方,實(shí)現(xiàn)隱藏那個div。

let selectBg = document.querySelector('.bg-btn');
let bgGroup = document.querySelector('.color-group');
let bgcolorBtn = document.querySelectorAll('.bgcolor-item');
let penDetail = document.getElementById("penDetail");
let activeBgColor = '#fff';


// 實(shí)現(xiàn)了切換背景顏色
for (let i = 0; i < bgcolorBtn.length; i++) {
    bgcolorBtn[i].onclick = function (e) {
        // 阻止冒泡
        e.stopPropagation();
        for (let i = 0; i < bgcolorBtn.length; i++) {
            bgcolorBtn[i].classList.remove("active");
            this.classList.add("active");
            activeBgColor = this.style.backgroundColor;
            setCanvasBg(activeBgColor);
        }
    }
}

document.onclick = function(){
    bgGroup.classList.remove('active');
}

selectBg.onclick = function(e){
    bgGroup.classList.add('active');
    e.stopPropagation();
}

7.實(shí)現(xiàn)改變畫筆粗細(xì)的功能

實(shí)現(xiàn)思路:

  1. 實(shí)現(xiàn)讓設(shè)置畫筆的屬性的對話框出現(xiàn)。

  2. 獲取相應(yīng)的元素節(jié)點(diǎn)。

  3. 當(dāng)input=range的元素發(fā)生改變的時候,獲取到的值賦值給lWidth。

  4. 然后設(shè)置context.lineWidth = lWidth。

let range1 = document.getElementById('range1');
let lWidth = 2;
let ifPop = false;

range1.onchange = function(){
    console.log(range1.value);
    console.log(typeof range1.value)
    thickness.style.transform = 'scale('+ (parseInt(range1.value)) +')';
    console.log(thickness.style.transform )
    lWidth = parseInt(range1.value*2);
}


// 畫線函數(shù)
function drawLine(x1,y1,x2,y2){
    // ...
    context.lineWidth = lWidth;
    // ...
}

// 點(diǎn)擊畫筆
brush.onclick = function(){
    eraserEnabled = false;
    brush.classList.add('active');
    eraser.classList.remove('active');
    if(!ifPop){
        // 彈出框
        console.log('彈一彈')
        penDetail.classList.add('active');
    }else{
        penDetail.classList.remove('active');
    }
    ifPop = !ifPop;
}

8.實(shí)現(xiàn)改變畫筆顏色的功能

實(shí)現(xiàn)思路跟 改變畫板背景顏色 的思路類似。

let aColorBtn = document.getElementsByClassName("color-item");

getColor();

function getColor(){
    for (let i = 0; i < aColorBtn.length; i++) {
        aColorBtn[i].onclick = function () {
            for (let i = 0; i < aColorBtn.length; i++) {
                aColorBtn[i].classList.remove("active");
                this.classList.add("active");
                activeColor = this.style.backgroundColor;
                ctx.fillStyle = activeColor;
                ctx.strokeStyle = activeColor;
            }
        }
    }
}

9.實(shí)現(xiàn)改變撤銷和重做的功能

實(shí)現(xiàn)思路:

  1. 保存快照:每完成一次繪制操作則保存一份 canvas 快照到 canvasHistory 數(shù)組(生成快照使用 canvas 的 toDataURL() 方法,生成的是 base64 的圖片);

  2. 撤銷和反撤銷:把 canvasHistory 數(shù)組中對應(yīng)索引的快照使用 canvas 的 drawImage() 方法重繪一遍;

  3. 繪制新圖像:執(zhí)行新的繪制操作時,刪除當(dāng)前位置之后的數(shù)組記錄,然后添加新的快照。

let undo = document.getElementById("undo");
let redo = document.getElementById("redo");

// ...
canvas.onmouseup = function(){
        painting = false;
        canvasDraw();
}

let canvasHistory = [];
let step = -1;

// 繪制方法
function canvasDraw(){
    step++;
    if(step < canvasHistory.length){
        canvasHistory.length = step;  // 截?cái)鄶?shù)組
    }
    // 添加新的繪制到歷史記錄
    canvasHistory.push(canvas.toDataURL());
}

// 撤銷方法
function canvasUndo(){
    if(step > 0){
        step--;
        // ctx.clearRect(0,0,canvas.width,canvas.height);
        let canvasPic = new Image();
        canvasPic.src = canvasHistory[step];
        canvasPic.onload = function () { ctx.drawImage(canvasPic, 0, 0); }
        undo.classList.add('active');
    }else{
        undo.classList.remove('active');
        alert('不能再繼續(xù)撤銷了');
    }
}
// 重做方法
function canvasRedo(){
    if(step < canvasHistory.length - 1){
        step++;
        let canvasPic = new Image();
        canvasPic.src = canvasHistory[step];
        canvasPic.onload = function () { 
            // ctx.clearRect(0,0,canvas.width,canvas.height);
            ctx.drawImage(canvasPic, 0, 0);
        }
        redo.classList.add('active');
    }else {
        redo.classList.remove('active')
        alert('已經(jīng)是最新的記錄了');
    }
}
undo.onclick = function(){
    canvasUndo();
}
redo.onclick = function(){
    canvasRedo();
}

10.兼容移動端

實(shí)現(xiàn)思路:

  • 判斷設(shè)備是否支持觸摸

  • true ,則使用 touch 事件; false ,則使用 mouse 事件

// ...
if (document.body.ontouchstart !== undefined) {
    // 使用touch事件
    anvas.ontouchstart = function (e) {
        // 開始觸摸
    }
    canvas.ontouchmove = function (e) {
        // 開始滑動
    }
    canvas.ontouchend = function () {
        // 滑動結(jié)束
    }
}else{
    // 使用mouse事件
    // ...
}
// ...

四、踩坑

 問題1:在電腦上對瀏覽器的窗口進(jìn)行改變,畫板不會自適應(yīng)

解決辦法:

onresize響應(yīng)事件處理中,獲取到的頁面尺寸參數(shù)是變更后的參數(shù) 。

當(dāng)窗口大小發(fā)生改變之后,重新設(shè)置canvas的寬高,簡單來說,就是窗口改變之后,給canvas.width和canvas.height重新賦值。

// 記得要執(zhí)行autoSetSize這個函數(shù)哦
function autoSetSize(){
    canvasSetSize();
    // 當(dāng)執(zhí)行這個函數(shù)的時候,會先設(shè)置canvas的寬高
    function canvasSetSize(){
        let pageWidth = document.documentElement.clientWidth;
        let pageHeight = document.documentElement.clientHeight;
        
        canvas.width = pageWidth;
        canvas.height = pageHeight;
    }
    // 在窗口大小改變之后,就會觸發(fā)resize事件,重新設(shè)置canvas的寬高
    window.onresize = function(){
        canvasSetSize();
    }
}

問題2:當(dāng)繪制線條寬度比較小的時候還好,一旦比較粗就會出現(xiàn)問題

解決辦法:看一下文檔,得出方法,只需要簡單修改一下 繪制線條的代碼 就行

// 畫線函數(shù)
function drawLine(x1,y1,x2,y2){
    context.beginPath();
    context.lineWidth = lWidth;
    //-----加入-----
    // 設(shè)置線條末端樣式。
    context.lineCap = "round";
    // 設(shè)定線條與線條間接合處的樣式
    context.lineJoin = "round";
    //-----加入-----
    context.moveTo(x1,y1);
    context.lineTo(x2,y2);
    context.stroke();
    context.closePath();
}

問題3:如何實(shí)現(xiàn)圓形的橡皮檫?

解決辦法:

canvas的API中,可以清除像素的就是clearRect方法,但是clearRect方法的清除區(qū)域矩形,畢竟大部分人的習(xí)慣中的橡皮擦都是圓形的,所以就引入了剪輯區(qū)域這個強(qiáng)大的功能,也就是clip方法。用法很簡單:

ctx.save()
ctx.beginPath()
ctx.arc(x2,y2,a,0,2*Math.PI);
ctx.clip()
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.restore();

上面那段代碼就實(shí)現(xiàn)了圓形區(qū)域的擦除,也就是先實(shí)現(xiàn)一個圓形路徑,然后把這個路徑作為剪輯區(qū)域,再清除像素就行了。有個注意點(diǎn)就是需要先保存繪圖環(huán)境,清除完像素后要重置繪圖環(huán)境,如果不重置的話以后的繪圖都是會被限制在那個剪輯區(qū)域中。

問題4:如何兼容移動端?

1.添加meta標(biāo)簽

因?yàn)闉g覽器初始會將頁面現(xiàn)在手機(jī)端顯示時進(jìn)行縮放,因此我們可以在meta標(biāo)簽中設(shè)置meta viewport屬性,告訴瀏覽器不將頁面進(jìn)行縮放,頁面寬度=用戶設(shè)備屏幕寬度

<meta name="viewport" content="width=device-width,
initial-scale=1,user-scalable=no,
maximum-scale=1.0,minimum-scale=1.0"/>

/*
頁面寬度=移動寬度 :width=device-width
用戶不可以縮放:user-scalable=no
縮放比例:initial-scale=1
最大縮放比例:maximum-scale=1.0
最小縮放比例:minimum-scale=1.0
*/

2.在移動端幾乎使用的都是touch事件,與PC端不同

由于移動端是觸摸事件,所以要用到H5的屬性touchstart/touchmove/touchend,但是PC端只支持鼠標(biāo)事件,所以要進(jìn)行特性檢測。

touch 事件里,是通過 .touches[0].clientX.touches[0].clientY 來獲取坐標(biāo)的,這點(diǎn)要和 mouse 事件區(qū)別開。

問題5:出現(xiàn)一個問題就是清空之后,重新畫,然后出現(xiàn)原來的畫的東西

這個嘛,問題不大,只不過是我漏寫context.beginPath(); ,也花了一點(diǎn)時間在上面解決bug,讓我想起“代碼千萬行,注釋第一行;編程不規(guī)范,同事兩行淚 ”,還是按照文檔操作規(guī)范操作好,真香?。。?/p>

html有什么特點(diǎn)

1、簡易性:超級文本標(biāo)記語言版本升級采用超集方式,從而更加靈活方便,適合初學(xué)前端開發(fā)者使用。 2、可擴(kuò)展性:超級文本標(biāo)記語言的廣泛應(yīng)用帶來了加強(qiáng)功能,增加標(biāo)識符等要求,超級文本標(biāo)記語言采取子類元素的方式,為系統(tǒng)擴(kuò)展帶來保證。  3、平臺無關(guān)性:超級文本標(biāo)記語言能夠在廣泛的平臺上使用,這也是萬維網(wǎng)盛行的一個原因。 4、通用性:HTML是網(wǎng)絡(luò)的通用語言,它允許網(wǎng)頁制作人建立文本與圖片相結(jié)合的復(fù)雜頁面,這些頁面可以被網(wǎng)上任何其他人瀏覽到,無論使用的是什么類型的電腦或?yàn)g覽器。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“HTML中如何實(shí)現(xiàn)一個canvas智繪畫板”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI