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

目录

绘制图像_缩放图像

绘制图像_图像切片

Canvas状态的保存和恢复

图形变形_平移

图形变形_旋转

图形变形_缩放

图形变形_变形

裁切路径

动画_时钟

动画_运动的小球

引入外部SVG


绘制图像_缩放图像

ctx.drawImage(img, x, y, width, height)
        img :图像数据,可以是 <img> 元素,也可以是 <canvas> 元素
        x :在目标 canvas 里放置图像的左上角的横坐标
        y :在目标 canvas 里放置图像的左上角的纵坐标
        width :图像在画布上的宽度
        height :图像在画布上的高度
 

       function draw(imgUrl, x, y) {// 定义imgvar 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个则是定义切片的目标显示位置和大小。

        //   定义图片var img = new Image()img.src = './assets/2.jpg'// 图片加载完成后绘制图像img.onload = function () {// 绘制图像// 从源图片(50,50)的位置开始切片,切片大小为50*50//切片在画布上的起始位置为(100,100),切片在画布上最终画出 //来的大小为200*200ctx.drawImage(img, 50, 50, 50,50, 100, 100, 200, 200)}//绘制矩形ctx.lineWidth = 30ctx.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() :将画布的样式恢复到之前保存的快照

        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 ,向上平移

     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),它是顺时针方向的,以弧度为单位的值。

        // 平移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) :用于缩放图像。
        x x 轴方向的缩放因子
        y y 轴方向的缩放因子
默认情况下,一个单位就是一个像素,缩放因子可以缩放单位,比如缩放因子 0.5 表示将大小缩小为原来的50%,缩放因子 10 表示放大十倍。
如果缩放因子为1,就表示图像没有任何缩放。
如果为-1,则表示方向翻转。 ctx.scale(-1, 1) 为水平翻转, ctx.scale(1, -1) 表示垂直翻转。

        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);
 

        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状态

        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)

动画_时钟

    <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 : hourconsole.log(hour)console.log(min)console.log(sec)// 绘制时针ctx.restore()ctx.save()ctx.lineWidth = 5ctx.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 = 4ctx.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 = 3ctx.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)


动画_运动的小球

        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 += stepXy -= 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、作为元素的背景图

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

   1.2、使用 img 引入

<img src="test.svg" alt="" >

 1.3、使用 object 引入

<object data="test.svg" type="image/svg+xml" />

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/215903.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

superset 后端增加注册接口

好烦啊-- &#xff1a;< 1.先定义modes: superset\superset\models\user.py # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information…

[PyTorch][chapter 66][强化学习-值函数近似]

前言 现实强化学习任务面临的状态空间往往是连续的,无穷多个。 这里主要针对这种连续的状态空间处理。后面DQN 也是这种处理思路。 目录&#xff1a; 1&#xff1a; 原理 2&#xff1a; 梯度更新 3&#xff1a; target 和 预测值 4 流程 一 原理 强化学习最重要的是得到 …

二阶线性微分算子

求导算子:&#xff0c;相当于 二阶线性微分算子 符号&#xff1a; 性质&#xff1a;设函数yy(x),,,二阶可导&#xff0c;C、C1,C2为常数&#xff0c;则有 叠加原理 设函数 ,都是L[y]的解&#xff0c; C1,C2是常数&#xff0c;则c1y1c2y2&#xff0c;也是L[y]的解 函数线性…

每日一题(LeetCode)----链表--链表最大孪生和

每日一题(LeetCode)----链表–链表最大孪生和 1.题目&#xff08;2130. 链表最大孪生和&#xff09; 在一个大小为 n 且 n 为 偶数 的链表中&#xff0c;对于 0 < i < (n / 2) - 1 的 i &#xff0c;第 i 个节点&#xff08;下标从 0 开始&#xff09;的孪生节点为第 (n…

相机设置参数:黑电平(Black Level)详解和示例

本文通过原理和示例对相机设置参数“黑电平”进行讲解&#xff0c;以帮助大家理解和使用。 原理 相机中黑电平原理是将电平增大&#xff0c;可以显示更多暗区细节&#xff0c;可能会损失一些亮区&#xff0c;但图像更多的关注暗区&#xff0c;获取完图像信息再减掉。只是为了…

VMware安装windows操作系统

一、下载镜像包 地址&#xff1a;镜像包地址。 找到需要的版本下载镜像包。 二、安装 打开VMware新建虚拟机&#xff0c;选择用镜像文件。将下载的镜像包加载进去即可。

Java枚举详解

一、什么是枚举类型 枚举类型是一种特殊的数据类型&#xff0c;用于定义一组固定的命名常量。枚举类型提供了一种更强大、更安全和更易读的方式来表示一组相关的常量。 在Java中&#xff0c;枚举类型是通过使用enum关键字来定义的。枚举类型可以包含一个或多个枚举常量&#xf…

DELL MD3600F存储重置管理软件密码

注意&#xff1a;密码清除可能会导致业务秒断&#xff0c;建议非业务时间操作 针对一台控制器操作即可&#xff0c;另一控制器会同步操作 重置后密码为空&#xff01; 需求&#xff1a;重置存储管理软件密码 管理软件中分配物理磁盘时提示输入密码(类似是否了解风险确认操作的提…

【网易云商】构建高效 SaaS 系统的技术要点与最佳实践

SaaS 是什么 定义 相信大家都对云服务中的 IaaS、PaaS、SaaS 早就有所耳闻&#xff0c;现在更是衍生出了 aPaaS、iPaaS、DaaS 等等的类似概念。对于 SaaS 也有各种各样的定义&#xff0c;本文给出的定义是&#xff1a; SaaS 是一种基于互联网提供服务和软件的交付模式&#xf…

Wireshark的捕获过滤器

Wireshark的过滤器&#xff0c;顾名思义&#xff0c;作用是对数据包进行过滤处理。具体过滤器包括捕获过滤器和显示过滤器。本文对捕获过滤器进行分析。 捕获过滤器&#xff1a;当进行数据包捕获时&#xff0c;只有那些满足给定的包含/排除表达式的数据包会被捕获。 捕获过滤器…

什么是轻量应用服务器?可以从亚马逊云科技的优势入手了解

什么是轻量应用服务器&#xff1f; 随着如今各行各业对云计算的需求越来越多&#xff0c;云服务器也被越来越多的企业所广泛采用。其中&#xff0c;轻量应用服务器是一种简单、高效、可靠的云计算服务&#xff0c;能够为开发人员、企业和个人提供轻量级的虚拟专用服务器&#x…

MeterSphere | 接口测试请求体中,int类型的入参实现动态化变量

项目场景&#xff1a; 在接口自动化的时候&#xff0c;要把上一个接口的 Int 变量传入到 下一个接口中进行使用&#xff0c;但编译器会出现 红色的 X 符号 问题描述 如何实现 int 类型的入参实现动态化变量&#xff1f; 解决方案&#xff1a; 忽视掉这个红色 X 号&#xff0…