百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Canvas学习笔记 | 多个示例详细讲述Canvas变形操作,干货

myzbx 2025-05-05 17:35 33 浏览

前言

大家好,我是汪小成。最近在学习Canvas。这篇文章是我学习Canvas变形操作时记的笔记,欢迎大家审阅。

简介

在Canvas中有如下三个基本变形操作:

  1. 图形平移:translate(x, y)
  2. 图形缩放:scale(x, y)
  3. 图形旋转:rotate(deg)

图形平移

在Canvas中,我们使用translate()方法来平移图形。图形平移指的是将图形沿x轴或y轴进行直线运行。平移不会改变图形的形状和大小。

语法

ctx.translate(x, y);

说明

x表示图形在x轴方向移动的距离,默认单位为px。当x为正数时,图形沿x轴正方向移动;当x为负数时,图形沿x轴反方向移动。 y表示图形在y轴方向移动的距离,默认单位为px。当y为正数时,图形沿y轴正方向移动;当y为负数时,图形沿y轴反方向移动。

示例一:简单示例

源码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>平移图形</title>
  </head>
  <body>
    <canvas id="canvas" width="200" height="150"
      style="border: 1px dashed #333333"></canvas>
    <script>
      window.onload = function () {
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");

        ctx.fillStyle = "red";
        ctx.fillRect(30, 30, 50, 40);
        
        ctx.translate(50, 50);
        ctx.fillStyle = "yellow";
        ctx.fillRect(30, 30, 50, 40);
      };
    </script>
  </body>
</html>

效果图:

说明:

上面的示例中,我们先绘制了一个红色的矩形,然后调用translate()方法将矩形在x轴方向和y轴方向分别平移50px,即黄色矩形的位置。平移操作,本质上来讲,是平移坐标系。

还有一点需要注意的是,translate()方法必须在fillRect()方法之前调用才有效。

先进行平移操作,然后绘制需要平移的图形

示例二:连续平移

源码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>连续平移</title>
  </head>
  <body>
    <canvas id="canvas" width="300" height="250"
      style="border: 1px dashed #333333"></canvas>
    <script>
      window.onload = function () {
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");

        ctx.fillStyle = "red";
        ctx.fillRect(30, 30, 50, 40);
        
        ctx.save();
        ctx.translate(50, 50);
        ctx.fillStyle = "yellow";
        ctx.fillRect(30, 30, 50, 40);
        ctx.restore();
    
        ctx.save();
        ctx.translate(100, 100);
        ctx.fillStyle = "blue";
        ctx.fillRect(30, 30, 50, 40);
        ctx.restore();
      };
    </script>
  </body>
</html>

效果图:

说明:

在平移图形前,我们调用了context.save()方法保存当前状态;在平移操作完成后,我们调用context.restore()方法恢复之前保存的状态`。这么做的目的是让每一次平移操作都以最初的状态为最根本的参照物

图形缩放

在Canvas中,我们使用scale()方法对图形进行缩放操作。这里的“缩放”包含“缩小”和“放大”两层含义。

语法

ctx.scale(x, y);

说明

x表示图形在x轴方向的缩放倍数。y表示图形在y轴方向的缩放倍数。x和y一般情况下都是正数。 当x或y取值为0~1之间时,图形会缩小;当x或y取值大于1时,图形会被放大。

示例

源码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>图形缩放</title>
  </head>
  <body>
    <canvas id="canvas" width="200" height="150"
      style="border: 1px dashed #333333"></canvas>
    <script>
      window.onload = function () {
        // 1、获取 Canvas 对象
        var canvas = document.getElementById("canvas");
        // 2、获取上下文环境对象
        var ctx = canvas.getContext("2d");
        // 绘制图形
        ctx.fillStyle = "#faeab3";
        ctx.fillRect(30, 30, 60, 60);
    
        // 缩放操作:将图形放大1.5倍
        ctx.scale(1.5, 1.5);
        ctx.fillStyle = "#ff0000";
        ctx.fillRect(30, 30, 60, 60);
      };
    </script>
  </body>
</html>

效果图:

本示例中,我们使用scale(1.5, 1.5)将图形放大了1.5倍。从效果图中,我们可以看出,图形左上角的坐标也放大了1.5位。是因为scale()方法除了会改变图形的大小之外,还会改变诸如线条宽度、左上角坐标等其他属性。

图形旋转

在Canvas中,我们使用rotate()方法旋转图形。

语法

ctx.rotate(angle);

说明

参数angle表示图形的旋转角度。取值范围为 -Math.PI * 2 ~ Math.PI * 2。当angle小于0时,图形顺时针旋转;当angle大小0时,图形逆时针旋转。

示例一:图形旋转简单示例

源码:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>图形旋转</title>
  </head>
  <body>
    <canvas id="canvas" width="200" height="150"
      style="border: 1px dashed #333333"></canvas>
    <script>
      window.onload = function () {
        // 1、获取 Canvas 对象
        var canvas = document.getElementById("canvas");
        // 2、获取上下文环境对象
        var ctx = canvas.getContext("2d");
        // 绘制图形
        ctx.fillStyle = "#ff0000";
        ctx.fillRect(100, 30, 50, 20);
        ctx.rotate(30 * Math.PI /180);
    
        // 为了方便比较,我们重新绘制了原来图形
        ctx.fillStyle = "#faeab3";
        ctx.fillRect(50, 30, 50, 20);
    
      };
    </script>
  </body>
</html>

效果图:

默认情况下,图形旋转时是以Canvas坐标原点为旋转中心的。如果我们想要以(x, y)为中心旋转,需要先使用translate(x, y)平移图形,然后旋转图形就是以(x, y)为中心旋转了。

示例二:旋转的半圆

这个示例相对来说有点复杂,我们先来看下效果图。

实现步骤:

  1. 绘制半圆;
  2. 让半圆旋转起来;
  3. 选取不同的圆心;
  4. 绘制多个半圆,并让这些半圆旋转起来。

步骤1、绘制半圆

ctx.beginPath();
ctx.arc(size / 2, size / 2, size / 4, 0, Math.PI, true);
ctx.strokeStyle = "white";
ctx.stroke();

步骤2、让半圆旋转起来

// 画布尺寸
let size = 800;

let canvas = document.getElementById("canvas");
canvas.width = canvas.height = size;

let ctx = canvas.getContext("2d");

// 半圆开始绘制的角度,用于控制半圆旋转
let angle = 0;

function draw() {
  window.requestAnimationFrame(draw);
  ctx.clearRect(0, 0, size, size);
  console.log("angle: " + angle);
  ctx.beginPath();
  ctx.arc(size / 2, size / 2, size / 4, angle, Math.PI + angle, true);
  ctx.strokeStyle = "white";
  ctx.stroke();

  angle += 0.02;
}

window.requestAnimationFrame(draw);

步骤3、选取不同的圆心

let size = 800;
// 圆心的数量
let num = 8;

let canvas = document.getElementById("canvas");
canvas.width = canvas.height = size;

let ctx = canvas.getContext("2d");

// 画布中央位置
var center = {
  x: canvas.width / 2,
  y: canvas.height / 2,
};

// 半径
let radius = 200;
// 初始角度
let angle = 0;

(function frame() {
  ctx.fillStyle = "#ff0000";
  for (let i = 0; i < num; i++) {
    const x = center.x + radius * Math.cos(Math.PI * 0.25 * i);
    const y = center.y + radius * Math.sin(Math.PI * 0.25 * i);
    // 圆心没有必要绘制出来,这里只是为了便于展示。
    ctx.beginPath();
    ctx.arc(x, y, 12, 0, 2 * Math.PI, true);
    ctx.fill();
  }
})();

步骤4、绘制多个半圆,并让这些半圆旋转起来。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>图形旋转</title>
  </head>
  <body>
    <canvas id="canvas"></canvas>
    <script>
      window.onload = function () {
        let size = 800;
        let num = 8;

        let canvas = document.getElementById("canvas");
        canvas.width = canvas.height = size;

        let ctx = canvas.getContext("2d");

        var center = {
          x: canvas.width / 2,
          y: canvas.height / 2,
        };

        // 半径
        let radius = 200;
        // 初始角度
        let angle = 0;

        (function frame() {
          window.requestAnimationFrame(frame);
          // 拖尾效果
          ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
          ctx.fillRect(0, 0, canvas.width, canvas.height);

          ctx.fillStyle = "#ff0000";
          for (let i = 0; i < num; i++) {
            const x = center.x + radius * Math.cos(Math.PI * 0.25 * i);
            const y = center.y + radius * Math.sin(Math.PI * 0.25 * i);

            // 绘制圆形
            ctx.beginPath();
            ctx.arc(
              x,
              y,
              size / 4,
              angle + Math.PI * 0.25 * i,
              Math.PI + angle + Math.PI * 0.25 * i,
              false
            );
            ctx.lineWidth = 3;

            ctx.strokeStyle = "hsl(" + angle * 60 + "deg,80%,50%)";
            ctx.stroke();

            angle += 0.008;
          }
        })();
      };
    </script>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      body {
        background-color: black;
        display: flex;
        vertical-align: middle;
        justify-content: center;
      }
    </style>
  </body>
</html>

上面的这段代码就是“旋转的半圆”示例程序的完整代码了。

附:清空画布&拖尾效果

清空画布

在Canvas中,我们使用clearRect()方法清空整个画布。

语法:

ctx.clearRect(0, 0, canvas.width, canvas.height);

拖尾效果

我们在绘制一些动画效果时有时候可能会需要使用拖尾效果让动画更美观一点。拖尾效果可以通过如下代码实现:

ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
ctx.fillRect(0, 0, canvas.width, canvas.height);




相关推荐

如何设计一个优秀的电子商务产品详情页

加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...

怎么在JS中使用Ajax进行异步请求?

大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...

中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革

前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...

前端监控 SDK 开发分享_前端监控系统 开源

一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...

Ajax 会被 fetch 取代吗?Axios 怎么办?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...

前端面试题《AJAX》_前端面试ajax考点汇总

1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...

Ajax 详细介绍_ajax

1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...

6款可替代dreamweaver的工具_替代powerdesigner的工具

dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...

我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊

接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...

福斯《死侍》发布新剧照 &quot;小贱贱&quot;韦德被改造前造型曝光

时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...

2021年超详细的java学习路线总结—纯干货分享

本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...

不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!

Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...

2025 年 Python 爬虫四大前沿技术:从异步到 AI

作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...

最贱超级英雄《死侍》来了!_死侍超燃

死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...

停止javascript的ajax请求,取消axios请求,取消reactfetch请求

一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...