GVKun编程网logo

HTML-Canvas的优越性能以及实际应用(html中canvas什么用)

19

对于想了解HTML-Canvas的优越性能以及实际应用的读者,本文将提供新的信息,我们将详细介绍html中canvas什么用,并且为您提供关于canvas-a11htmlANDcanvas.html_

对于想了解HTML-Canvas的优越性能以及实际应用的读者,本文将提供新的信息,我们将详细介绍html中canvas什么用,并且为您提供关于canvas-a11htmlANDcanvas.html_html/css_WEB-ITnose、HTML 5 Canvas性能、html2canvas 将html绘制到canvas中 [不建议使用]、html2canvas-html图片合成-canvas生成图片的有价值信息。

本文目录一览:

HTML-Canvas的优越性能以及实际应用(html中canvas什么用)

HTML-Canvas的优越性能以及实际应用(html中canvas什么用)

HTML绘图届的前辈:SVG

Canvas是HTML5时代引入的“新”标签。与很多标签不同,Canvas不具有自己的行为,只将一组API 展现给客户端 JavaScript ,让开发者使用脚本把想绘制的东西画到一张画布上。

在HTML5之前,人们通常使用SVG来在页面上绘制出图形。SVG使用XML来定义图形,就像使用HTML标签和样式定义DIV一样,我们也可以将一个空白的DIV想象为长方形的SVG,两者的设计思想是相通的,SVG的本质就是一个DOM元素。而Canvas则不同,Canvas提供的是 JavaScript 的绘图 API,而不是像 SVG那样使用XML 描述绘图,通过JavaScript API直接完成绘制,比起修改XML来说要更简便、更直接。

除了定义的方式不同,Canvas和DOM(当然也包含SVG)的差异更多的体现在浏览器的渲染方式上。

浏览器在做页面渲染时,Dom元素是作为矢量图进行渲染的。每一个元素的边距都需要单独处理,浏览器需要将它们全都处理成像素才能输出到屏幕上,计算量十分庞大。当页面上内容非常多,存在大量DOM元素的时候,这些内容的渲染速度就会变得很慢。

(Canvas)

而Canvas与DOM的区别则是Canvas的本质就是一张位图,类似img标签,或者一个div加了一张背景图(background-image)。所以,DOM那种矢量图在渲染中存在的问题换到Canvas身上就完全不同了。在渲染Canvas时,浏览器只需要在JavaScript引擎中执行绘制逻辑,在内存中构建出画布,然后遍历整个画布里所有像素点的颜色,直接输出到屏幕就可以了。不管Canvas里面的元素有多少个,浏览器在渲染阶段也仅需要处理一张画布。

然而这样更加强大的功能,不可避免的让使用canvas渲染有很高的门槛。Google Docs在构建Canvas的过程中重新定义了往常已经被人们所熟悉的内容,例如精确定位、文本选择、拼写检查、重画调优等。为什么更多开发者还是选择了接纳Canvas这个门槛更高的技术路线呢?这就得回到Canvas的最大优势:渲染性能。

Canvas的渲染模式

这里的渲染是指浏览器将页面的代码呈现为屏幕上内容的过程。Canvas和Dom的渲染模式完全不同,搞清楚这个差异对理解Canvas的性能优势至关重要。

Dom:驻留模式

驻留模式(Retained Mode)是Dom在浏览器中的渲染模式。下图粗略展示了这一过程的工作流程。

(驻留模式)

DOM的核心是标签,一种文本标记型语言,多样性很强且多个标签之间存在各种关联(如在同一个DIV下设置为float的子DIV)。浏览器为了更好的处理这些DOM元素,减少对绘制API的调用,就设计了一套将中间结果存放于内存的“驻留模式”。首先,浏览器会将解析DOM相关的全部内容(包含HTML标签、样式和JavaScript),将其转化为场景(scene)和模型(model)存储到内存中,然后再调用系统的绘制API(如Windows程序员熟悉的GDI/GDI+),把这些中间产物绘制到屏幕。

驻留模式通过场景和模型缓存减少了对绘制API的调用频次,将性能压力转移到场景和模型生成阶段,即浏览器需要根据DOM上下文和BOM中的尺寸数据,“自行判断”每一个元素的绘制结果。

Canvas:快速模式

Canvas采用了和DOM不同的快速模式(Immediate Mode),让我们先来看看快速模式是如工作的:

(快速模式)

Canvas的应用优点

上面介绍的两种不同的模式直接造成了Dom和Canvas的性能差异。对于使用快速模式渲染的Canvas而言,浏览器的每次重绘都是基于代码的,不存在能让处理流程变慢的多层解析,所以它真的很快。除了快之外,Canvas的灵活性也大大超出DOM。我们可以通过代码精确的控制如何、何时绘制出我们想要的效果。

在资源消耗上,DOM的驻留模式意味着场景中每增加一点东西就需要额外消耗一些内存,而Canvas并没有这个问题。这个差异会随着页面元素的数量增多而愈加明显。以B端的企业应用场景为例,表单那种数据量比较小的场景,不同渲染模式带来的效果差异并不明显;但在工业制造、金融财会等类Excel电子表格操作的场景下,单元格数量动辄便是上百万(5万行x 20列)甚至上亿个,浏览器需要对表格所有单元格本身内容进行渲染,同时还涉及到丰富的数据处理,情况就完全不同了。

(Web页面上的电子表格,包含1百万个单元格)

在Canvas出现之前,在前端渲染表格时只能通过构建复杂的DOM来实现。这种方式下,浏览器的性能成为了Web应用瓶颈,让很多开发者放弃了在浏览器上实现电子表格的想法。

在Canvas出现后,快速模式带来的性能优势无疑是一个巨大的亮点,大量、复杂的DOM渲染处理带来的性能问题终于有了解决途径。

回到电子表格的应用场景,业内已经出现了使用Canvas绘制画布的表格组件,这类组件在渲染数据层时不仅无需重复创建和销毁DOM元素,在画布的绘制过程中,也比Dom元素渲染的限制更少。除了表格之外,Canvas也为数字孪生可视化大屏、页面游戏等场景带来了变革。

(数字孪生大屏,精确控制各种形状、样式)

总结

总结一下,在渲染模式上,Canvas站在了DOM的对面,浏览器对其内容一无所知,一切渲染的权利回到了开发者的手上,这个改变带来了显著的性能优势。此外,我们可以使用Canvas绘制种类更为丰富的UI元素,如线形、特殊图形等,通过画法逻辑,还可以实现更加精准的UI界面渲染,解决了浏览器差异造成的样式误差,让更多应用场景可以顺利迁移到Web平台上来。

参考资料:

· Canvas的Wiki介绍

· Canvas社区

· 基于Canvas表格组件 SpreadJS

到此这篇关于HTML-Canvas的优越性能以及实际应用的文章就介绍到这了,更多相关Canvas性能及应用内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

canvas-a11htmlANDcanvas.html_html/css_WEB-ITnose

canvas-a11htmlANDcanvas.html_html/css_WEB-ITnose

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>Document</title></head><style>    #canvas-wrapper{        width: 1200px;        height: 800px;        position: relative;        margin:50px auto;    }    #canvas{        border: 1px #ddd solid;    }    #controller{        position: absolute;        top:30px;        left:30px;        background:rgba(0,85,116,0.7);        padding:5px 20px 25px 20px;        border-radius: 10px 10px;    }    #controller h1{        color: white;        font-weight: bold;        font-family: "Microsoft Yahei";    }    #controller #canvas-btn{        display: inline-block;        background: #8b0;        color: white;        font-size: 14px;        padding: 5px 15px;    }    #controller #canvas-btn:hover{        text-decoration: none;        background:#7a0;    }    #controller .color-btn{        display: inline-block;        padding:5px 15px;        border-radius: 6px 6px;        font-size: 14px;        margin-top: 10px;        margin-right: 5px;        text-decoration: none;    }    #controller .color-btn:hover{        text-decoration: none;    }    #controller #white-color-btn{        background-color: white;    }    #controller #black-color-btn{        background-color: black;    }</style><body>    <div id="canvas-wrapper">        <canvas id="canvas">            当前游览器不支持Canvas,请更换游览器再试!        </canvas>        <div id="controller">            <h1>Canvas 绘图之旅</h1>            <a href="#" id="canvas-btn">stop</a>            <a href="#"id="white-color-btn">white</a>            <a href="#"id="black-color-btn">black</a>        </div>    </div>    <script>        var balls = [];        var isMoving = true;        var themeColor = "white";        var canvas = document.getElementById("canvas");        window.onload = function(){            canvas.width = 1200;            canvas.height = 800;                        if(canvas.getContext(''2d'')){                var context = canvas.getContext(''2d'');                // 产生100个小球                for(var i=0;i<100;i++){                    var R = Math.floor(Math.random()*255);                    var G = Math.floor(Math.random()*255);                    var B = Math.floor(Math.random()*255);                    var radius = Math.random()*50+20;                    aBall = {                        color : "rgb(" + R + "," + G + "," + B + ")",                        radius : radius,                        x : Math.random()*(canvas.width-2*radius) + radius,                        y : Math.random()*(canvas.height-2*radius) + radius,                        vx : (Math.random()*5 + 5) * Math.pow(-1,Math.floor(Math.random()*100)),                        vy : (Math.random()*5 + 5) * Math.pow(-1,Math.floor(Math.random()*100)),                    }                    balls[i] = aBall;                }                // 绘制并运动                setInterval(function(){                    draw(context);                    if(isMoving){                        update(canvas.width,canvas.height)                    }                },50)                // stop                document.getElementById("canvas-btn").onclick = function(event){                    if(isMoving){                        isMoving = false;                        this.text = "start";                    }else{                        isMoving = true;                        this.text = "stop";                    }                    return false;                }                 // white                document.getElementById("white-color-btn").onclick = function(event){                    themeColor = "white";                    return false;                }                // black                document.getElementById("black-color-btn").onclick = function(event){                    themeColor = "black";                    return false;                }            }else{                alert("当前游览器不支持Canvas,请更换游览器再试!")            }        }        function draw(cxt){            // var canvas = cxt.canvas;            cxt.clearRect(0,0,canvas.width,canvas.height);            if(themeColor == "black"){                console.log("black theme");                cxt.fill;                cxt.fillRect(0,0,canvas.width,canvas.height)            }            for(var i=0;i<balls.length;i++){                cxt.fillStyle = balls[i].color;                cxt.beginPath();                    cxt.arc(balls[i].x,balls[i].y,balls[i].radius,0,Math.PI*2);                cxt.closePath();                cxt.fill();            }        }        function update(){            for(var i=0;i<balls.length;i++){                balls[i].x += balls[i].vx;                balls[i].y += balls[i].vy;                // 边缘检测                if(balls[i].x - balls[i].radius <= 0){                    balls[i].vx = -balls[i].vx;                    balls[i].x = balls[i].radius;                }                if(balls[i].x + balls[i].radius >= canvas.width){                    balls[i].vx = -balls[i].vx;                    balls[i].x = canvas.width - balls[i].radius;                }                if(balls[i].y - balls[i].radius <= 0){                    balls[i].vy = -balls[i].vy;                    balls[i].y = balls[i].radius;                }                if(balls[i].y + balls[i].radius >= canvas.height){                    balls[i].vy = -balls[i].vy;                    balls[i].y = canvas.height - balls[i].radius;                }            }        }    </script></body></html>
登录后复制

 

HTML 5 Canvas性能

HTML 5 Canvas性能

我刚刚开始使用画布 HTML5对象.为了性能测试,我做了一点 ping pong game.

我可以使用任何性能改进吗?

球似乎是蓝色的,带有一点红色,但我声明它应该是黄色的.我怎样才能解决这个问题?

解决方法

这应该有助于你的球颜色;

function drawBall (x,y,r) {
    ctx.beginPath();
    ctx.fill;
    ctx.arc(x,r,Math.PI*2,false);
    ctx.closePath();
    ctx.fill(); //added
    fps++;
}

function drawP1 (h) {
    ctx.fill;
    ctx.fillRect(0,h,20,100);
    //ctx.fill(); // remove in P2 also
    fps++;
    return true;
};

fill()不适用于fillRect(),后者绘制一个填充的rectagle,fill()是填充pathes.

使用简单的乒乓球比赛你可以改进的并不多,但我会给出一些关于帆布表现的一般建议:

> fillStyle / strokeStyle调用很昂贵,避免切换颜色.
>绘制复杂的形状也很昂贵.你可以绘制然后使用像素api来渲染它们
>尝试将渲染和处理分开,这将为您提供改进空间
>尝试使用纯js进行高FPS游戏/动画

如上所述,非常一般的建议,可能不适合每个案例.

html2canvas 将html绘制到canvas中 [不建议使用]

html2canvas 将html绘制到canvas中 [不建议使用]

 

原文链接: html2canvas 将html绘制到canvas中 [不建议使用]

上一篇: ramda 例子

下一篇: interactjs 拖拽 缩放 的交互库

这个有很多隐藏的bug, 不太建议在生产环境中使用

推荐使用vdom包装一层, 用fabric画到canvas中, 或者用后端去画, 再或者用无头浏览器去截图

而且对于mac和windows的chrome表现也不一致....

下面是转换出来的canvas, 用beta版本还可以接受, 但是依然丢失了文字

 

用官方的版本转换出来的有问题

<!DOCTYPE html>
<html lang="en">
<head>
<!--  <script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>-->
  <script src="https://cdn.bootcdn.net/ajax/libs/html2canvas/0.5.0-beta4/html2canvas.js"></script>
  <style>
    body {
      width: 100vw;
      height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
    }

    .wrap {
      width: 300px;
      height: 300px;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      border: 1px solid blue;
    }

    .bg-img {
      width: 100%;
      height: 100%;
      background: url("./t.jpg") no-repeat;
      background-position-x: center;
      background-position-y: center;
      background-size: contain;
    }

    .text-input {
      width: 400px;
      height: 200px;
      border: 1px solid red;
      background: gray;
      opacity: .5;
      position: absolute;
    }

  </style>
</head>
<body>

<div>
  <div></div>
  <div contentEditable="true">
  </div>
</div>

<button onclick="showCanvas()">show</button>

<script>
  function showCanvas() {
    html2canvas(document.querySelector(".wrap", {
      width: 300,
      height: 300
    })).then(canvas => {
      document.body.appendChild(canvas)
    });
  }
</script>
</body>
</html>

 

html2canvas-html图片合成-canvas生成图片

html2canvas-html图片合成-canvas生成图片

作用

  • html2canvas可以通过纯JS对浏览器端经行截屏,但截图的精确度还有待提高,部分css不可识别,所以在canvas中不能完美呈现原画面样式

支持的浏览器

  • Firefox 3.5+
  • Google Chrome
  • Opera 12+
  • IE9+
  • Safari 6+

基本语法

//两个参数:所需要截图的元素id,截图后要执行的函数, canvas为截图后返回的最后一个canvas
 html2canvas(document.getElementById(''id'')).then(function(canvas) {document.body.appendChild(canvas);});

可用参数

参数名称 类型 默认值 描述
allowTaint boolean false Whether to allow cross-origin images to taint the canvas---允许跨域
background string #fff Canvas background color, if none is specified in DOM. Set undefined for transparent---canvas的背景颜色,如果没有设定默认透明
height number null Define the heigt of the canvas in pixels. If null, renders with full height of the window.---canvas高度设定
letterRendering boolean false Whether to render each letter seperately. Necessary if letter-spacing is used.---在设置了字间距的时候有用
logging boolean false Whether to log events in the console.---在console.log()中输出信息
proxy string undefined Url to the proxy which is to be used for loading cross-origin images. If left empty, cross-origin images won''t be loaded.---代理地址
taintTest boolean true Whether to test each image if it taints the canvas before drawing them---是否在渲染前测试图片
timeout number 0 Timeout for loading images, in milliseconds. Setting it to 0 will result in no timeout.---图片加载延迟,默认延迟为0,单位毫秒
width number null Define the width of the canvas in pixels. If null, renders with full width of the window.---canvas宽度
useCORS boolean false Whether to attempt to load cross-origin images as CORS served, before reverting back to proxy--这个我也不知道是干嘛的

 

 

请服搭务器环境查看

生成后:

html生成canvas canvas.toDataURL 生成base64图片

底部4个小图,由于跨域,2个无法生成,设置允许跨域的图是可以生成的。

 

 

html2canvas(document.getElementById(''htmlDom''), {
        useCORS:true,//设置该属性,图片请求头带Access-Control-Allow-Origin: * 的可以生成,图片请求如有带301跳转,则无法生成
        onrendered: function(canvas) {
            window.can = canvas;
            console.log(canvas);
            $("#tarPic").attr("src",canvas.toDataURL())
            document.body.appendChild(canvas);
            },
    // width: 300,
    // height: 300
    });

 示例代码:https://files.cnblogs.com/files/zhidong123/htmlToCanvas.rar

https://github.com/zhidong10/solutions/tree/master/htmlToCanvas

 

今天的关于HTML-Canvas的优越性能以及实际应用html中canvas什么用的分享已经结束,谢谢您的关注,如果想了解更多关于canvas-a11htmlANDcanvas.html_html/css_WEB-ITnose、HTML 5 Canvas性能、html2canvas 将html绘制到canvas中 [不建议使用]、html2canvas-html图片合成-canvas生成图片的相关知识,请在本站进行查询。

本文标签: