zoukankan      html  css  js  c++  java
  • canvas入门基础,七巧板、五角星、粒子时钟等

    创建一个canvas

    HTML

    创建canvas元素

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

    设置宽高使用标签width,height属性,注意不能使用css或style样式

    display默认为inline

    <canvas id="canvas" width="1024" height="768" style="border: 1px solid #ccc; display: block; margin: 0 auto;">当前浏览器不支持canvas,请更换浏览器后再试</canvas>
    

    JavaScript

    获取canvas

    //获取canvas元素
    var canvas  = document.getElementById('canvas')
    //使用context进行绘制
    var context = canvas.getCountext('2d');
    

    除了通过上面HTML属性设置canvas宽高之外,当然也可以用javascript来设置

    canvas.width = 1024
    canvas.height = 768
    

    也可以使用javascript检测浏览器是否支持canvas

    if(canvas.getContext('2d')){
      var context = canvas.getCountext('2d');
    }else{
      alert('当前浏览器不支持canvas,请更换浏览器后再试')
    }
    

    补充——解决vscode编辑canvas没有代码提示问题

    在定义canvas之前加入如下注释即可

    /** @type {HTMLCanvasElement} */ 
    var canvas = document.getElementById('canvas')
    

    画一条直线

    画布左上角坐标为默认为(0,0),那么我想画一条坐标从(100,100)到(700,700)的直线,该怎么画呢?

    //起笔
    context.beginPath()
    //路径
    context.moveTo(100, 100)
    context.lineTo(700, 700)
    //落笔
    context.closePath()
    //绘制路径
    context.stroke()
    

    beginPath(),closePath()

    beginPath()重新规划一条路线

    closePath()结束当前的路线,如果当前的路线没有封闭则会自动封闭路线

    只绘制一个图形时可以省略这两个方法,但是如果当你再画第二个图形时,下面的context.stroke()会把上面的覆盖,所以注意beginPath(),closePath()的使用

    closePath()的另外一个作用就是封闭图形,如果绘制多个图形又不想封闭图形该怎么做呢?这里可以只写beginPath()省略后面的closePath(),从而绘制多个图形时都不会产生影响,beginPath(),closePath()不一定要成对出现

    beginPath()后的moveTo()可以被lineTo()代替,即可以不写moveTo(),详见下面画五角星中的应用。

    线条属性

    linewidth

    线条宽度,属性值为数字

    lineCap

    线条的边角,注意这个属性的头是突出的,所以比默认线条长度两边各多出一个半径的长度。lineCap只有线条首尾有效果,线条衔接处无效。衔接处使用lineJoin

    描述
    butt 默认。向线条的每个末端添加平直的边缘。
    round 向线条的每个末端添加圆形线帽。
    square 向线条的每个末端添加正方形线帽。
    lineJoin

    当两条线条交汇时,创建边角

    描述
    bevel 创建斜角。
    round 创建圆角。
    miter 默认。创建尖角。
    miterLimit

    w3school教程

    画一个三角形

    context.beginPath()
    //路径
    context.moveTo(100, 100)
    context.lineTo(700, 700)
    context.lineTo(100, 700)
    //封闭
    context.closePath()
    context.stroke()
    

    把线条粗细改成5个像素,颜色为红色

    context.lineWidth = 5
    context.strokeStyle = 'red'
    

    填充封闭空间

    //填充颜色
    context.fillStyle = '#38f'
    context.fill();
    

    补充——stroke和fill调用先后顺序对绘图的影响

    先调用stroke在调用fill,绘制的效果看上去lineWidth只绘制出来一半,这是因为先填充会把边框覆盖掉一半,正确顺序是先调用fill在调用stroke,用边框颜色去覆盖填充颜色就能达到理想效果。

    补充——canvas的”状态“和”绘制“代码书写技巧

    canvas是基于状态进行绘制的,在编程中可以把状态和绘制分开写,这样会更加直观简洁。例如:

    // 路径
    context.beginPath()
    context.moveTo(100, 100)
    context.lineTo(700, 700)
    context.lineTo(100, 700)
    context.closePath()
    // 状态
    context.lineWidth = 5
    context.fillStyle = '#38f'
    context.strokeStyle = 'red'
    // 绘制
    context.fill();
    context.stroke()
    

    绘制七巧板

    参考代码如下,注意beginPath(),closePath()的位置

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas-七巧板</title>
    </head>
    <body>
        <canvas id="canvas" style="border: 1px solid #ccc; display: block; margin: 0 auto;">
            当前浏览器不支持canvas,请更换浏览器后再试
        </canvas>
        <script>
            var tangram = [
                { trajectory: [ {x: 0, y: 0}, {x: 800, y: 0}, {x: 400, y: 400} ], color: '#caff67' },
                { trajectory: [ {x: 0, y: 0}, {x: 400, y: 400}, {x: 0, y: 800} ], color: '#67becf' },
                { trajectory: [ {x: 800, y: 0}, {x: 800, y: 400}, {x: 600, y: 600}, {x: 600, y: 200} ], color: '#ef3d61' },
                { trajectory: [ {x: 600, y: 200}, {x: 600, y: 600}, {x: 400, y: 400} ], color: '#f9f51a' },
                { trajectory: [ {x: 400, y: 400}, {x: 600, y: 600}, {x: 400, y: 800}, {x: 600, y: 600} ], color: '#a594c0' },
                { trajectory: [ {x: 200, y: 600}, {x: 400, y: 800}, {x: 0, y: 800} ], color: '#fa8ecc' },
                { trajectory: [ {x: 800, y: 400}, {x: 800, y: 800}, {x: 400, y: 800} ], color: '#f6ca29' }
            ]
            // 绘制
            function draw(piece, cxt){
                cxt.beginPath()
                cxt.moveTo(piece.trajectory[0].x, piece.trajectory[0].y)
                for(var j = 1; j < piece.trajectory.length; j ++){
                    cxt.lineTo(piece.trajectory[j].x, piece.trajectory[j].y)
                }
                cxt.closePath()
                cxt.fillStyle = piece.color
                cxt.fill();
            }
            window.onload = function(){
                /** @type {HTMLCanvasElement} */ 
                var canvas = document.getElementById('canvas'),
                    context = canvas.getContext('2d')
                // 画布宽高
                canvas.width = 800
                canvas.height = 800
                for(var i = 0; i < tangram.length; i ++){
                    draw(tangram[i], context)
                }
            }
        </script>
    </body>
    </html>
    

    画一个圆弧

    //x:圆的中心的 x 坐标
    //y:圆的中心的 y 坐标
    //r:圆的半径
    //sAngle:起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)
    //eAngle:结束角,以弧度计
    //counterclockwise:可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。默认顺时针
    context.arc(x,y,r,sAngle,eAngle,counterclockwise);
    

    画一个圆弧

    context.beginPath()
    context.arc(400, 400, 100, 0, 1.5*Math.PI, false)
    context.closePath()
    context.stroke()
    

    如果不想封闭,删除context.closePath()即可

    画一个圆

    弧度从0到2π即可

    context.beginPath()
    context.arc(400, 400, 100, 0, 2*Math.PI, false)
    context.stroke()
    

    小球落体运动

    参考代码

    注意:测试时最好注释render()中的第一行代码 cxt.clearRect(0, 0, WIDTH, HEIGHT) ,这样可以显示出运动轨迹。

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>ball-fall</title>
    </head>
    <body>
        <canvas id="canvas" style="border: 2px solid #ccc; display: block; margin: 20px auto 0;">
            当前浏览器不支持canvas,请更换浏览器后再试
        </canvas>
        <script>
            var ball = {x: 900, y: 200, vx: -4, vy: 0, g: 1.5}
            var WIDTH = 1000, HEIGHT = 700, RIDIUS = 15
            window.onload = function(){
                /** @type {HTMLCanvasElement} */ 
                var canvas = document.getElementById('canvas'),
                    context = canvas.getContext('2d')
                // 画布宽高
                canvas.width = WIDTH
                canvas.height = HEIGHT
                setInterval(function(){
                    render(context)
                    update()
                }, 50)
            }
            function render(cxt){
                cxt.clearRect(0, 0, WIDTH, HEIGHT)
                cxt.beginPath()
                cxt.arc(ball.x, ball.y, RIDIUS, 0, 2*Math.PI)
                cxt.closePath()
                cxt.fillStyle = '#f0f'
                cxt.fill();
            }
            function update(){
                ball.x += ball.vx
                ball.y += ball.vy
                if(ball.y >= HEIGHT-RIDIUS){
                    ball.y = HEIGHT-RIDIUS
                    ball.vy = -ball.vy*0.7
                }else{
                    ball.vy += ball.g
                }
            }
        </script>
    </body>
    </html>
    

    代码中首先定义了小球的基本属性:横坐标,纵坐标,水平速度,垂直速度,加速度

    update()中用到了一个摩擦系数为0.7

    update()

    这里的重点是update函数部分,为什么会这样写?示例代码用到了摩擦系数0.7,运动轨迹看起来差别不大。如果没有摩擦,观察下面几种写法有什么不同。

    // 方法一
    function update(){
      ball.x += ball.vx
      ball.y += ball.vy
      ball.vy += ball.g
      if(ball.y >= HEIGHT-RIDIUS){
        ball.y = HEIGHT-RIDIUS
        ball.vy = -ball.vy
        // 测试打印出最大垂直速度
        console.log(ball.vy)
      }
    }
    // 方法二
    function update(){
      ball.x += ball.vx
      ball.y += ball.vy
      if(ball.y >= HEIGHT-RIDIUS){
        ball.y = HEIGHT-RIDIUS
        ball.vy = -ball.vy
        // 测试打印出最大垂直速度
        console.log(ball.vy)
      }
      ball.vy += ball.g
    }
    // 方法三
    function update(){
      ball.x += ball.vx
      ball.y += ball.vy
      if(ball.y >= HEIGHT-RIDIUS){
        ball.y = HEIGHT-RIDIUS
        ball.vy = -ball.vy
        // 测试打印出最大垂直速度
        console.log(ball.vy)
      }else{
        ball.vy += ball.g
      }
    }
    

    这几种方法都没有摩擦系数,仅仅只是 ball.vy += ball.g 的位置不同而已,经过测试你会发现:方法一弹跳后最高点会越来越高,方法二弹跳后最高点会越来越低,而方法三则都在同一最高点。通过打印出的最大垂直速度不难发现,方法一造成的原因是每次小球落到最低点都多加了一次 ball.g ,方法二同理。方法三是在水平线以上才会累加垂直速度。

    上抛效果

    其实上抛效果很简单,只需要将 ball.vy 的初始值设置为负值即可,这里需要注意 ball.vy 的值尽量按照加速度的值来设定,最好是加速度的倍数,这样能够保证最高点的垂直速度为0,运动轨迹都有统一的焦点。

    这里还有一个问题:设置过上抛效果后,第一个最高点可能和之后的最高点不同,造成这个原因是因为小球落到最低处时的位置不一定刚好等于HEIGHT-RIDIUS,示例代码中是强制不让小球出界。如下

     if(ball.y >= HEIGHT-RIDIUS){
        ball.y = HEIGHT-RIDIUS
      }
    

    如果注释ball.y = HEIGHT-RIDIUS这行代码你会发现路径的最高点都一样了。

    这里最简单的解决方法就是调整ball的初始位置,使其下落到最低点时刚好是边界的高度,即ball.y == HEIGHT-RIDIUS

    动态粒子时钟效果

    参考代码 演示digit.js文件地址

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>canvas-clock</title>
        <style>
            * {margin: 0; padding: 0;}
        </style>
    </head>
    <body>
        <canvas id="canvas" style="display: block;background-color: black;">当前浏览器不支持canvas,请更换浏览器后再试</canvas>
        <script>
            var WIDTH, HEIGHT, LEFT, TOP, RADIUS, timeSeconds, balls = [], timer
            window.onload = function () {
                /** @type {HTMLCanvasElement} */
                var canvas = document.getElementById('canvas'),
                    context = canvas.getContext('2d')
                // 自适应窗口大小
                WIDTH = document.documentElement.clientWidth
                HEIGHT = document.documentElement.clientHeight
                // 边距(先计算RADIUS)
                RADIUS = Math.round(WIDTH / 170)
                LEFT = Math.round((WIDTH - 107 * RADIUS) / 2)
                TOP = Math.round((HEIGHT - 20 * RADIUS) / 3)
                timeSeconds = getTime()
                // 画布宽高
                canvas.width = WIDTH
                canvas.height = HEIGHT
                animation(context)
                // 监听当前页面是否被隐藏
                document.addEventListener('visibilitychange', function () {
                    if (document.visibilityState == 'hidden') {
                        clearInterval(timer)
                    } else if (document.visibilityState == 'visible') {
                        animation(context)
                    }
                })
            }
            // 小球下落动画
            function animation(context) {
                timer = setInterval(function () {
                    render(context)
                    update()
                }, 50)
            }
            // 渲染页面
            function render(cxt) {
                var hours = parseInt(timeSeconds / 3600),
                    minutes = parseInt((timeSeconds - hours * 3600) / 60)
                seconds = timeSeconds % 60
                // 首先清空画布
                cxt.clearRect(0, 0, WIDTH, HEIGHT)
                renderDigit(LEFT, TOP, parseInt(hours / 10), cxt)
                renderDigit(LEFT + 15 * RADIUS, TOP, parseInt(hours % 10), cxt)
                renderDigit(LEFT + 30 * RADIUS, TOP, 10, cxt)
                renderDigit(LEFT + 39 * RADIUS, TOP, parseInt(minutes / 10), cxt)
                renderDigit(LEFT + 54 * RADIUS, TOP, parseInt(minutes % 10), cxt)
                renderDigit(LEFT + 69 * RADIUS, TOP, 10, cxt)
                renderDigit(LEFT + 78 * RADIUS, TOP, parseInt(seconds / 10), cxt)
                renderDigit(LEFT + 93 * RADIUS, TOP, parseInt(seconds % 10), cxt)
                // 渲染下落的小球
                for (var i = 0; i < balls.length; i++) {
                    cxt.fillStyle = balls[i].color
                    cxt.beginPath()
                    cxt.arc(balls[i].x, balls[i].y, RADIUS, 0, 2 * Math.PI, true)
                    cxt.closePath()
                    cxt.fill()
                }
            }
            // 更新画布
            function update() {
                var nextTimeSeconds = getTime(),
                    nextHours = parseInt(nextTimeSeconds / 3600),
                    nextMinutes = parseInt((nextTimeSeconds - nextHours * 3600) / 60),
                    nextSeconds = nextTimeSeconds % 60,
                    curHours = parseInt(timeSeconds / 3600),
                    curMinutes = parseInt((timeSeconds - curHours * 3600) / 60),
                    curSeconds = timeSeconds % 60
                if (nextSeconds !== curSeconds) {
                    // 判断被改变的数字,判断小球位置
                    if (parseInt(curHours / 10) != parseInt(nextHours / 10)) {
                        addBalls(LEFT + 0, TOP, parseInt(curHours / 10))
                    }
                    if (parseInt(curHours % 10) != parseInt(nextHours % 10)) {
                        addBalls(LEFT + 15 * RADIUS, TOP, parseInt(curHours / 10))
                    }
                    if (parseInt(curMinutes / 10) != parseInt(nextMinutes / 10)) {
                        addBalls(LEFT + 39 * RADIUS, TOP, parseInt(curMinutes / 10))
                    }
                    if (parseInt(curMinutes % 10) != parseInt(nextMinutes % 10)) {
                        addBalls(LEFT + 54 * RADIUS, TOP, parseInt(curMinutes % 10))
                    }
                    if (parseInt(curSeconds / 10) != parseInt(nextSeconds / 10)) {
                        addBalls(LEFT + 78 * RADIUS, TOP, parseInt(curSeconds / 10))
                    }
                    if (parseInt(curSeconds % 10) != parseInt(nextSeconds % 10)) {
                        addBalls(LEFT + 93 * RADIUS, TOP, parseInt(nextSeconds % 10))
                    }
                    // 同步显示时间
                    timeSeconds = nextTimeSeconds
                }
                updateBalls()
            }
            // 按照数字添加小球个数
            function addBalls(x, y, num) {
                for (var i = 0; i < digit[num].length; i++){
                    for (var j = 0; j < digit[num][i].length; j++){
                        if (digit[num][i][j] == 1) {
                            var aBall = {
                                x: x + j * 2 * RADIUS + RADIUS,
                                y: y + i * 2 * RADIUS + RADIUS,
                                g: 1.5 + Math.random(),
                                vx: Math.pow(-1, Math.ceil(Math.random() * 1000)) * 4,
                                vy: -5,
                                color: getRandomColor()
                            }
                            balls.push(aBall)
                        }
                    }
                }
            }
            // 更新下落小球的位置
            function updateBalls() {
                for (var i = 0; i < balls.length; i++) {
                    balls[i].x += balls[i].vx
                    balls[i].y += balls[i].vy
                    // 反弹效果
                    if (balls[i].y >= HEIGHT - RADIUS) {
                        balls[i].y = HEIGHT - RADIUS
                        balls[i].vy = - Math.abs(balls[i].vy) * 0.75
                    }else{
                    	balls[i].vy += balls[i].g
                    }
                }
                // 删除超出界面外的小球
                for (var i = 0; i < balls.length; i++) {
                    if (balls[i].x + RADIUS < 0 || balls[i].x - RADIUS > WIDTH) {
                        balls.splice(i, 1)
                    }
                }
            }
            // 获取时间
            function getTime() {
                var curTime = new Date()
                return curTime.getHours() * 3600 + curTime.getMinutes() * 60 + curTime.getSeconds()
            }
            // 渲染数字
            function renderDigit(x, y, num, cxt) {
                cxt.fillStyle = "rgb(0,102,153)"
                for (var i = 0; i < digit[num].length; i++) {
                    for (var j = 0; j < digit[num][i].length; j++) {
                        if (digit[num][i][j] == 1) {
                            cxt.beginPath()
                            cxt.arc(x + j * 2 * RADIUS + RADIUS, y + i * 2 * RADIUS + RADIUS, RADIUS, 0, 2 * Math.PI)
                            cxt.closePath()
                            cxt.fill()
                        }
                    }
                }
            }
            // 获取随机颜色
            function getRandomColor() {
                return '#' +
                    (function (color) {
                        return (color += '5678956789defdef'[Math.floor(Math.random() * 16)]) &&
                            (color.length == 6) ? color : arguments.callee(color)
                    })('')
            }
        </script>
        <script src="./digit.js"></script>
    </body>
    </html>
    

    画一个矩形

    通过上面的方法,已经可以用线条画出一个封闭矩形,除此之外canvas还为我们提供了直接绘制矩形的方法。调用即可

    context.rect(x,y,width,height)
    context.fillRect(x,y,width,height)
    context.strokeRect(x,y,width,height)
    

    画一个五角星

    参考代码

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>start</title>
    </head>
    <body>
        <canvas id="canvas" style="border: 2px solid #ccc; display: block; margin: 20px auto 0;">
            当前浏览器不支持canvas,请更换浏览器后再试
        </canvas>
        <script>
            window.onload = function(){
                /** @type {HTMLCanvasElement} */ 
                var canvas = document.getElementById('canvas'),
                    context = canvas.getContext('2d')
                // 画布宽高
                canvas.width = 800
                canvas.height = 700
    
                context.lineWidth = 10
                drawStart(context, 150, 300, 400, 400)
            }
            // 小圆半径,大圆半径,x,y坐标,顺时针旋转角度(默认0)
            function drawStart(cxt, r, R, x, y, rot = 0){
                cxt.beginPath()
                for(var i = 0; i < 5; i ++){
                    cxt.lineTo(Math.cos((18 + i*72 - rot)/180 * Math.PI) * R + x, 
                               -Math.sin((18 + i*72 - rot)/180 * Math.PI) * R + y)
                    cxt.lineTo(Math.cos((54 + i*72 - rot)/180 * Math.PI) * r + x, 
                               -Math.sin((54 + i*72 - rot)/180 * Math.PI) * r + y)
                }
                cxt.closePath()
                cxt.stroke()
            }
        </script>
    </body>
    </html>
    

    思路:五角星的五个内顶点在小圆上,外顶点在大圆上。以圆心为坐标原点,五角星上顶点在y轴,建立坐标系,注意canvas中y轴方向向下。五角星中每个顶点坐标相差72度,简单计算即可得到五角星各个顶点的位置。

    图解

    star

    星空效果

    参考代码

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>starts</title>
        <style>*{margin: 0; padding: 0;}</style>
    </head>
    <body>
        <canvas id="canvas" style="display: block; background-color: black;">
            当前浏览器不支持canvas,请更换浏览器后再试
        </canvas>
        <script>
            var WIDTH, HEIGHT 
            window.onload = function(){
                /** @type {HTMLCanvasElement} */ 
                var canvas = document.getElementById('canvas'),
                    context = canvas.getContext('2d')
                // 画布宽高
                WIDTH = document.documentElement.clientWidth
                HEIGHT = document.documentElement.clientHeight
                canvas.width = WIDTH
                canvas.height = HEIGHT
    
                for(var i = 0; i < 100; i ++){
                    var r = Math.random()*10 + 10,
                        x = Math.random()*(WIDTH - 2*r) + r,
                        y = Math.random()*(HEIGHT - 2*r) + r,
                        a = Math.random()*360
                    drawStart(context, x, y, r/2, r, a)
                }
            }
            function drawStart(cxt, x, y, r, R, rot = 0){
                cxt.beginPath()
                for(var i = 0; i < 5; i ++){
                    cxt.lineTo(Math.cos((18 + i*72 - rot)/180 * Math.PI) * R + x,
                               -Math.sin((18 + i*72 - rot)/180 * Math.PI) * R + y)
                    cxt.lineTo(Math.cos((54 + i*72 - rot)/180 * Math.PI) * r + x, 
                               -Math.sin((54 + i*72 - rot)/180 * Math.PI) * r + y)
                }
                cxt.closePath()
                cxt.fillStyle = 'yellow'
                cxt.fill()
            }
        </script>
    </body>
    </html>
    

    线性渐变

    示例代码

    <!DOCTYPE html>
    <html lang="zh_CN">
    <head>
        <meta charset="UTF-8">
        <title>linear-gradient</title>
    </head>
    <body>
        <canvas id="canvas" style="display: block; border: 2px solid #ccc; margin: 30px auto 0;">
            当前浏览器不支持canvas,请更换浏览器后再试
        </canvas>
        <script>
            window.onload = function () {
                /** @type {HTMLCanvasElement} */
                var canvas = document.getElementById('canvas'),
                    context = canvas.getContext('2d')
                // 画布宽高
                canvas.width = 700
                canvas.height = 700
    
                var linearGrad = context.createLinearGradient(0, 0, 700, 700)
                linearGrad.addColorStop(0.0, 'red')
                linearGrad.addColorStop(0.25, 'yellow')
                linearGrad.addColorStop(0.5, 'green')
                linearGrad.addColorStop(0.75, 'blue')
                linearGrad.addColorStop(1.0, 'coral')
                context.fillStyle = linearGrad
                context.fillRect(0, 0, 700, 700)
            }
        </script>
    </body>
    </html>
    

    径向渐变

    示例代码

    <!DOCTYPE html>
    <html lang="zh_CN">
    <head>
        <meta charset="UTF-8">
        <title>radial-gradient</title>
    </head>
    <body>
        <canvas id="canvas" style="display: block; border: 2px solid #ccc; margin: 30px auto 0;">
            当前浏览器不支持canvas,请更换浏览器后再试
        </canvas>
        <script>
            window.onload = function () {
                /** @type {HTMLCanvasElement} */
                var canvas = document.getElementById('canvas'),
                    context = canvas.getContext('2d')
                // 画布宽高
                canvas.width = 700
                canvas.height = 700
    
                var radialGrad = context.createRadialGradient(350, 350, 0, 350, 350, 400)
                radialGrad.addColorStop(0.0, 'red')
                radialGrad.addColorStop(0.25, 'yellow')
                radialGrad.addColorStop(0.5, 'green')
                radialGrad.addColorStop(0.75, 'blue')
                radialGrad.addColorStop(1.0, 'coral')
                context.fillStyle = radialGrad
                context.fillRect(0, 0, 700, 700)
            }
        </script>
    </body>
    </html>
    

    使用图片、画布、或者video

    createPattern(img, repeat-style)
    createPattern(canvas, repeat-style)
    createPattern(video, repeat-style)
    // repeat-style: no-repeat
    // 				repeat-x
    // 				repeat-x
    // 				repeat-y
    // 				repeat
    
    完结~
  • 相关阅读:
    QOMO Linux 4.0 正式版发布
    LinkChecker 8.1 发布,网页链接检查
    pgBadger 2.1 发布,PG 日志分析
    Aletheia 0.1.1 发布,HTTP 调试工具
    Teiid 8.2 Beta1 发布,数据虚拟化系统
    zLogFabric 2.2 发布,集中式日志存储系统
    开源电子工作套件 Arduino Start Kit 登场
    Piwik 1.9 发布,网站访问统计系统
    Ruby 1.9.3p286 发布,安全修复版本
    toBraille 1.1.2 发布,Java 盲文库
  • 原文地址:https://www.cnblogs.com/lwlblog/p/12346205.html
Copyright © 2011-2022 走看看