HTML新特性【缩放图像、图像切片、平移、旋转、缩放、变形、裁切路径、时钟、运动的小球】(二)-全面详解(学习总结---从入门到深化)

目录

绘制图像_缩放图像

绘制图像_图像切片

Canvas状态的保存和恢复

图形变形_平移

图形变形_旋转

图形变形_缩放

图形变形_变形

裁切路径

动画_时钟

动画_运动的小球

引入外部SVG


绘制图像_缩放图像

ctx.drawImage(img, x, y, width, height)

img :图像数据,可以是 <img> 元素,也可以是 <canvas> 元素

x:在目标 canvas 里放置图像的左上角的横坐标

y:在目标 canvas 里放置图像的左上角的纵坐标

width :图像在画布上的宽度

height :图像在画布上的高度

javascript 复制代码
       function draw(imgUrl, x, y) {
            // 定义img
            var img = new Image()
            img.src = imgUrl
            // 图片加载完后绘制图像
            img.onload = function () {
                // 绘制图像
                ctx.drawImage(img, x, y, 200, 200)
           }
       }
        // 通过遍历绘制九张图片铺满画布
        for (var i = 0; i < 3; i++) {
            for (var j = 0; j < 3; j++) {
                draw('./assets/4.jpg', i * 200, j * 200)
           }
       }

绘制图像_图像切片

ctx.drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

img:图像数据,可以是 <img> 元素,也可以是 <canvas> 元素·

sx:图像源被切的开始位置的横坐标

sy :图像源被切的开始位置的纵坐标

sWidth:图像源被切的宽度

sHeight :图像源被切的高度

dx:图像在画布的开始位置的横坐标

dy:图像在画布的开始位置的纵坐标

dWidth :图像在画布的宽度

dHeight :图像在画布的高度

第一个参数和其它的是相同的,都是一个图像或者另一个 canvas 的引用。

剩余的8个参数前4个是定义图像源的切片位置和大小,后4个则是定义切片的目标显示位置和大小。

javascript 复制代码
        //   定义图片
        var img = new Image()
        img.src = './assets/2.jpg'
        // 图片加载完成后绘制图像
        img.onload = function () {
            // 绘制图像
            // 从源图片(50,50)的位置开始切片,切片大小为50*50
            //切片在画布上的起始位置为(100,100),切片在画布上最终画出 //来的大小为200*200
            ctx.drawImage(img, 50, 50, 50,50, 100, 100, 200, 200)
       }
         //绘制矩形
        ctx.lineWidth = 30
        ctx.strokeStyle = 'yellow'
        ctx.strokeRect(100, 100, 200, 200)

Canvas状态的保存和恢复

1、 ctx.save() :将画布的当前状态保存起来,相当于在内存之中产生一个样式快照

一个绘画状态包括:

1.1、当前的一些样式:strokeStyle , fillStyle , lineWidth , lineCap , lineJoin ,lineDashOffset , shadowOffsetX , shadowOffsetY , shadowBlur , shadowColor ,
font , textAlign , textBaseline

1.2、当前应用的变形(即移动,旋转和缩放)

1.3、当前的裁切路径(clipping path)

2、ctx.restore() :将画布的样式恢复到之前保存的快照

javascript 复制代码
        ctx.fillRect(0, 0, 300, 300)//绘制矩形
        ctx.save()//保存当前状态
        ctx.fillStyle = 'green'//设置填充色
        ctx.fillRect(30, 30, 240,240)//绘制矩形
        ctx.save()//保存当前状态
        ctx.fillStyle='#fff'//设置填充色
        ctx.fillRect(60,60,180,180)//绘制矩形
        ctx.restore()//恢复上一个状态
        ctx.fillRect(90,90,120,120)
        ctx.restore()//恢复上上一个状态
        ctx.fillRect(120,120,60,60)

图形变形_平移

ctx.translate(x, y)
x:是左右偏移量,x>0 ,向右平移,x<0 ,向左平移
y:是上下偏移量,y>0 ,向下平移, y<0 ,向上平移

javascript 复制代码
     for (var i = 0; i < 2; i++) {
            for (var j = 0; j < 2; j++) {
                ctx.restore()//恢复上一次状态
                ctx.save()//保存上一次状态
                //产生平移
                ctx.translate(50 * i + 10, 50 * j + 10)
                //设置填充颜色
                ctx.fillStyle = ['red', 'green'][j]
                //绘制小矩形
                ctx.fillRect(0, 0, 25, 25)
           }
       }

图形变形_旋转

ctx.rotate(angle) :以 原点为中心 旋转 坐标系

angle :旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。

javascript 复制代码
        // 平移
        ctx.translate(100, 100)
        for (var i = 1; i < 7; i++) {
            // 旋转坐标系
            ctx.rotate((Math.PI*2)/6)
            // 绘制圆形
            ctx.beginPath()
            ctx.fillStyle = 'red'
            ctx.arc(0, 30, 5, 0, Math.PI * 2)
            ctx.fill()
       }

图形变形_缩放

ctx.scale(x,y):用于缩放图像。

xx轴方向的缩放因子

yy 轴方向的缩放因子

默认情况下,一个单位就是一个像素,缩放因子可以缩放单位,比如缩放因子 0.5表示将大小缩小为原来的50%,缩放因子10表示放大十倍。

如果缩放因子为1,就表示图像没有任何缩放。

如果为-1,则表示方向翻转。**ctx.scale(-1, 1)**为水平翻转,**ctx.scale(1, -1)**表示垂直翻转。

javascript 复制代码
        ctx.translate(100, 100)//平移
        ctx.save()//保存当前状态
        // 绘制第一个矩形
        ctx.fillStyle = 'green'
        ctx.fillRect(0, 20, 100, 100)
        //绘制X轴所在的一条直线
        ctx.beginPath()
        ctx.moveTo(0,0)
        ctx.lineTo(500,0)
        ctx.stroke()
        
        // 绘制第二个矩形
        ctx.scale(0.5, 0.5)//缩放网格
        ctx.fillStyle = 'yellow'
        ctx.fillRect(0, 40, 100, 100)
        
        ctx.restore()//恢复之前的状态
        ctx.scale(1, -1)//垂直方向翻转
        // 绘制第一个矩形
        ctx.fillStyle = 'green'
        ctx.fillRect(0, 20, 100, 100)
        // 绘制第二个矩形
        ctx.scale(0.5, 0.5)//缩放网格
        ctx.fillStyle = 'yellow'
        ctx.fillRect(0, 40, 100, 100)

图形变形_变形

1、 ctx.transform(a, b, c, d, e, f):接受变换矩阵的六个元素作为参数,完成缩放、平移和倾斜等变形。

a:x轴方向缩放

b:x轴方向倾斜

c:y轴方向倾斜

d:y轴方向缩放

e:x轴方向平移

f:y轴方向平移

2、默认状态:transform(1,0,0,1,0,0)

变换矩阵: a c e

[ b d f ]

0 0 1

(x,y) 经过矩阵变换后得到**(x',y')**

1 、x' = ax + cy + e;

2 、y' = bx + dy + f;

ctx.setTransform(a, b, c, d, e, f) :重置并创建新的变换矩阵
ctx.resetTransform() :重置当前变形为单位矩阵,它和调用以下语句是一样的:
ctx.setTransform(1, 0, 0, 1, 0, 0);

javascript 复制代码
        ctx.fillRect(0, 0, 100, 100);//绘制参考矩形
        ctx.fillStyle='green'
        // ctx1.transform(0.5, 0, 0, 0.5, 0, 0);//缩放
        // ctx1.transform(1, 0, 0, 1, 50, 50);//平移
        // ctx1.transform(1, 1, 0, 1, 0, 0);//倾斜
        ctx.transform(0.5, 1, 0, 0.5, 50, 50);//综合变形
        ctx.fillRect(0, 100, 100, 100);//绘制变形后的矩形
        ctx.setTransform(0.5, 0, 0, 0.5, 0, 0);//重置并创建新的变化矩阵
        ctx.fillRect(0, 400, 100, 100);//绘制重置并创建新变形后的矩形

裁切路径

**ctx.clip() :**将构建的路径转换为裁剪路径,裁切路径确定好之后,再绘制图形,裁切路径内的图形可以显示,裁切路径外的图形不显示。

默认情况下,canvas 有一个与它自身一样大的裁切路径(也就是没有裁切效果)。

提示:

裁切路径也属于canvas状态

javascript 复制代码
        var ctx = document.getElementById('canvas').getContext('2d')
        ctx.save()//保存状态
        ctx.fillRect(0, 0, 200, 200)//绘制一个跟画布一样大小的黑色矩形
        ctx.arc(100, 100, 50, 0, 2 * Math.PI)//定义个圆形的路径
        ctx.clip()
        // ctx.restore()
        // 绘制一个跟画布一样大小的黄色矩形
        ctx.fillStyle = 'yellow'
        ctx.fillRect(0, 0, 200, 200)

动画_时钟

javascript 复制代码
    <canvas width="150" height="150" id="canvas"></canvas>
    <script>
        var ctx = document.getElementById('canvas').getContext('2d')
        ctx.translate(75, 75)//移动原点到画布的正中心
        ctx.rotate(-Math.PI / 2)//逆时针旋转九十度
        ctx.lineCap = 'round'//设置线条末端样式
        ctx.save()
        clock()
        function clock() {
            ctx.clearRect(-75, -75, 150, 150)
            //   绘制一个跟画布一样大小的粉色矩形
            ctx.fillStyle = 'pink'
            ctx.fillRect(-75, -75, 150, 150)
            // 获取当前时间
            var now = new Date()
            // 绘制小时的刻度
            ctx.lineWidth = 3//设置线条宽度
            for (var i = 0; i < 12; i++) {
                ctx.beginPath()
                ctx.rotate(Math.PI / 6)
                ctx.moveTo(68, 0)
                ctx.lineTo(75, 0)
                ctx.stroke()
           }
            // 绘制分钟的刻度
            ctx.lineWidth = 2//设置线条宽度
            for (var i = 0; i < 60; i++) {
                // 如果i除以五的余数不为0,则代表不跟小时的刻度重合,则绘制分钟的刻度
                if (i % 5 != 0) {
                    ctx.beginPath()
                    ctx.moveTo(72, 0)
                    ctx.lineTo(75, 0)
                    ctx.stroke()
               }
                ctx.rotate(Math.PI / 30)
           }

           var hour = now.getHours()
            var min = now.getMinutes()
            var sec = now.getSeconds()
            hour = hour > 12 ? hour - 12 : hour
            console.log(hour)
            console.log(min)
            console.log(sec)
            // 绘制时针
            ctx.restore()
            ctx.save()
            ctx.lineWidth = 5
            ctx.rotate((Math.PI / 6) * (hour + min / 60 + sec / 3600))
            ctx.beginPath()
            ctx.moveTo(-10, 0)
            ctx.lineTo(40, 0)
            ctx.stroke()
            // 绘制分针
            ctx.restore()
            ctx.save()
            ctx.lineWidth = 4
            ctx.rotate((Math.PI / 30) * (min + sec / 60))
            ctx.beginPath()
            ctx.moveTo(-10, 0)
            ctx.lineTo(60, 0)
            ctx.stroke()

         // 绘制秒针
            ctx.restore()
            ctx.save()
            ctx.lineWidth = 3
            ctx.rotate((Math.PI / 30) * (sec))
            ctx.beginPath()
            ctx.moveTo(-10, 0)
            ctx.lineTo(60, 0)
            ctx.strokeStyle = 'red'
            ctx.stroke()
            // 在原点处绘制红色小圆点
            ctx.beginPath()
            ctx.arc(0, 0, 5, 0, 2 * Math.PI)
            ctx.fillStyle = 'red'
            ctx.fill()
            // 在秒针末端绘制小圆圈
            ctx.beginPath()
            ctx.arc(65, 0, 5, 0, 2 * Math.PI)
            ctx.stroke()
            ctx.restore()
       }
        setInterval(function () {
            clock()
        }, 1000)

动画_运动的小球

javascript 复制代码
        var c = document.getElementById('canvas')
        var ctx = c.getContext('2d')
        var raf;
        var x = 250//定义小球的圆心的默认横坐标
        var y = 250//定义小球的圆形的默认纵坐标
        var stepX = 5//定义小球每次运动水平方向的偏移矢量
        var stepY = 2//定义小球每次运动垂直方向的偏移矢量
        function draw() {
            // ctx.clearRect(0, 0, 500, 500)
            // 每次绘制前都画一个带点透明的矩形,这样可以产生尾巴的效果
            ctx.fillStyle = 'rgba(255,255,255,0.3)';
            ctx.fillRect(0, 0, 500, 500);
            //根据小球的新的圆心的位置绘制小球
            ctx.beginPath()
            ctx.arc(x, y, 20, 0, 2 * Math.PI)
            ctx.fillStyle = 'red'
            ctx.fill()
            // 判断小球的位置.如果超出
            if (x + 20 >= 500 || x - 20 <= 0) {
                stepX = -stepX;
           }
            if (y + 20 >= 500 || y - 20 <= 0) {
                stepY = -stepY;
           }
            // 改变小球的位移
            x += stepX
            y -= stepY
       }
        function anim() {
            draw()//绘制小球
            //告诉浏览器我要执行一个动画,传递进去的回调函数会在每次重绘之前调用,一般情况下每秒执行60次
            raf = window.requestAnimationFrame(anim)
       }
        anim()
        // 监听鼠标的移动事件,让小球跟着鼠标移动位置
        c.addEventListener('mousemove',function (e) {
          window.cancelAnimationFrame(raf);
            x = e.offsetX;
            y = e.offsetY;
            draw()
       });
        // 点击鼠标,则继续开始动画
        c.addEventListener('click', function (e) {
            anim()
      });

引入外部SVG

SVG :遵循 XML 标准,用来定义可缩放矢量图形。

1、引入外部svg文件的方式

1.1、作为元素的背景图

javascript 复制代码
#con {
            width:100px;
            height: 100px;
            background: url('./test.svg') no-repeat;
       }

1.2、使用 img 引入

javascript 复制代码
<img src="test.svg" alt="" >

1.3、使用 object 引入

javascript 复制代码
<object data="test.svg" type="image/svg+xml" />
相关推荐
光影少年8 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_9 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891111 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾12 分钟前
前端基础-html-注册界面
前端·算法·html
Dragon Wu14 分钟前
前端 Canvas 绘画 总结
前端
CodeToGym19 分钟前
Webpack性能优化指南:从构建到部署的全方位策略
前端·webpack·性能优化
~甲壳虫20 分钟前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫24 分钟前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js
Cwhat25 分钟前
前端性能优化2
前端
熊的猫1 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js