【Canvas技法】绘制正三角形、切角正三角形、圆角正三角形

【图例】

【代码】

<!DOCTYPE html>
<html lang="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<head>
     <title>绘制正三角形、切角正三角形、圆角正三角形</title>
     <style type="text/css">
     .centerlize{
        margin:0 auto;
        width:1200px;
     }
     </style>
     </head>

     <body οnlοad="init();">
        <div class="centerlize">
            <canvas id="myCanvas" width="12px" height="12px" style="border:1px dotted black;">
                如果看到这段文字说您的浏览器尚不支持HTML5 Canvas,请更换浏览器再试.
            </canvas>
            <img id="myImg" src="125.png" style="display:none;"/>
        </div>
     </body>
</html>
<script type="text/javascript">
<!--
/*****************************************************************
* 将全体代码(从<!DOCTYPE到script>)拷贝下来,粘贴到文本编辑器中,
* 另存为.html文件,再用chrome浏览器打开,就能看到实现效果。
******************************************************************/

// canvas的绘图环境
var ctx;

// 高宽
const WIDTH=512;
const HEIGHT=512;

// 舞台对象
var stage;

//-------------------------------
// 初始化
//-------------------------------
function init(){
    // 获得canvas对象
    var canvas=document.getElementById('myCanvas');  
    canvas.width=WIDTH;
    canvas.height=HEIGHT;

    // 初始化canvas的绘图环境
    ctx=canvas.getContext('2d');  
    ctx.translate(WIDTH/2,HEIGHT/2);// 原点平移到画布中央

    // 准备
    stage=new Stage();    
    stage.init();

    // 开幕
    animate();
}

// 播放动画
function animate(){    
    stage.update();    
    stage.paintBg(ctx);
    stage.paintFg(ctx);     

    // 循环
    if(true){
        window.requestAnimationFrame(animate);   
    }
}

// 舞台类
function Stage(){

    // 初始化
    this.init=function(){
        
    }

    // 更新
    this.update=function(){
        
    }

    // 画背景
    this.paintBg=function(ctx){
        ctx.clearRect(-WIDTH/2,-HEIGHT/2,WIDTH,HEIGHT);// 清屏        
    
        // 正三角形
        var arr=createRegTriArr(0,-128,80);
        ctx.beginPath();
        for(var i=0;i<arr.length;i++){
            ctx.lineTo(arr[i].x,arr[i].y);
        }
        ctx.closePath();
        ctx.fillStyle="RGB(215,204,182)";
        ctx.fill();
        ctx.lineWidth=2;
        ctx.strokeStyle="RGB(104,20,20)";
        ctx.stroke();

        // 切角三角形
        var arr=createRegTriArr(-128,128,80);
        drawChamferedTriangle(ctx,arr[0],arr[1],arr[2],12);
        ctx.fillStyle="RGB(215,204,182)";
        ctx.fill();
        ctx.lineWidth=2;
        ctx.strokeStyle="RGB(104,20,20)";
        ctx.stroke();

        // 圆角三角形
        drawRoundTriangle(ctx,128,128,80,10);
        ctx.fillStyle="RGB(215,204,182)";
        ctx.fill();
        ctx.lineWidth=2;
        ctx.strokeStyle="RGB(104,20,20)";
        ctx.stroke();

        // 版权
        ctx.textBaseline="bottom";
        ctx.textAlign="center";
        ctx.font = "8px consolas";
        ctx.fillStyle="black";
        ctx.fillText("逆火原创",WIDTH/2-40,HEIGHT/2-10);
    }

    // 画前景
    this.paintFg=function(ctx){
        
        
    }
}

/*----------------------------------------------------------
函数:创建一个二维坐标点
x:横坐标
y:纵坐标
Pt即Point
----------------------------------------------------------*/
function createPt(x,y){
    var retval={};
    retval.x=x;
    retval.y=y;
    return retval;
}

/*----------------------------------------------------------
函数:创建一个以x,y为中心,r为半径的正三角形数组
ctx:绘图上下文
x:三角形中心横坐标
y:三角形中心纵坐标
r:三角形中心到顶点的长度
arr[0]为右下,arr[1]为左下,arr[2]为正上。
----------------------------------------------------------*/
function createRegTriArr(x,y,r){
    var arr=new Array();

    for(var i=0;i<3;i++){
        var theta=Math.PI*2/3*i+Math.PI/6;
        var pt=createPt(r*Math.cos(theta)+x,r*Math.sin(theta)+y);
        arr.push(pt);
    }

    return arr;
}

/*----------------------------------------------------------
函数:用于绘制切角正三角形
ctx:绘图上下文
ptRight:右顶点
ptLeft:左顶点
ptTop:上顶点
chamferLength:切角长度
----------------------------------------------------------*/
function drawChamferedTriangle(ctx,ptRight,ptLeft,ptTop,chamferLength){
    ctx.beginPath();
    ctx.moveTo(ptRight.x-chamferLength,ptRight.y);
    ctx.lineTo(ptLeft.x+chamferLength,ptLeft.y);
    ctx.lineTo(ptLeft.x+chamferLength/2,ptLeft.y-chamferLength*1.732/2);
    ctx.lineTo(ptTop.x-chamferLength/2,ptTop.y+chamferLength*1.732/2);
    ctx.lineTo(ptTop.x+chamferLength/2,ptTop.y+chamferLength*1.732/2);
    ctx.lineTo(ptRight.x-chamferLength/2,ptRight.y-chamferLength*1.732/2);
    ctx.closePath();
}

/*----------------------------------------------------------
函数:用于绘制圆角正三角形
ctx:绘图上下文
x:三角形中心横坐标
y:三角形中心纵坐标
r:三角形中心到顶点的长度
filletRadius:圆角半径
----------------------------------------------------------*/
function drawRoundTriangle(ctx,x,y,r,filletRadius){
    var arr=createRegTriArr(x,y,r);
    var arrLeft=createRegTriArr(arr[0].x,arr[0].y,filletRadius);
    var arrRight=createRegTriArr(arr[1].x,arr[1].y,filletRadius);
    var arrTop=createRegTriArr(arr[2].x,arr[2].y,filletRadius);

    ctx.beginPath();
    ctx.moveTo(arrTop[0].x,arrTop[0].y);
    ctx.lineTo(arrLeft[2].x,arrLeft[2].y);
    ctx.arcTo(arrLeft[0].x,arrLeft[0].y,arrLeft[1].x,arrLeft[1].y,filletRadius);
    ctx.lineTo(arrRight[0].x,arrRight[0].y);
    ctx.arcTo(arrRight[1].x,arrRight[1].y,arrRight[2].x,arrRight[2].y,filletRadius);
    ctx.lineTo(arrTop[1].x,arrTop[1].y);
    ctx.arcTo(arrTop[2].x,arrTop[2].y,arrTop[0].x,arrTop[0].y,filletRadius);
    ctx.closePath();
}

/*--------------------------------------------------
闻君有白玉美人,妙手雕成,极尽妍态,不胜心向往之。
今夜子时,当踏月来取。
君素雅达,必不致令我徒劳往返也。
---------------------------------------------------*/
//-->
</script>

END

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络—传输层UDP协议:原理、应用

​ &#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;2月のセプテンバー 1:21━━━━━━️&#x1f49f;──────── 5:21 &#x1f504; ◀️ ⏸ ▶️ ☰ &am…

leetcode.45题:跳跃游戏II

Leetcode.45题&#xff1a;跳跃游戏II /* 题意的理解&#xff1a; nums[0] 只能跳 1 ~ nums[0]步 依次类推&#xff1a;从nums[0] - nums[n - 1] 最少需要多少步数 nums 2 3 1 1 4 nums[0] 2,初始只能跳 1/2步&#xff0c;如跳1步&#xff0c;达到nums[1] 而nums[1] 3,顾第二…

网络篇04 | 应用层 mqtt(物联网)

网络篇04 | 应用层 mqtt&#xff08;物联网&#xff09; 1. MQTT协议介绍1.1 MQTT简介1.2 MQTT协议设计规范1.3 MQTT协议主要特性 2 MQTT协议原理2.1 MQTT协议实现方式2.2 发布/订阅、主题、会话2.3 MQTT协议中的方法 3. MQTT协议数据包结构3.1 固定头&#xff08;Fixed header…

uboot操作指令2

文章目录 一、FAT 格式文件系统操作命令1.fatinfo 命令2.fatls 命令3.fstype 命令4.fatload命令-将EMMC数据复制到DRAM中4.fatwrite命令-将DRAM数据复制到EMMC中 二、Boot操作指令1.bootz2.boot命令 一、FAT 格式文件系统操作命令 &#x1f4a6; 有时候需要在 uboot 中对 SD 卡…

MYSQL08_页的概述、内部结构、文件头、文件尾、最大最小记录、页目录、区段表

文章目录 ①. 页的概述、大小②. 页的内部结构③. 第一部分 - 文件头④. 第一部分 - 文件尾⑤. 第二部分 - 空闲、用户记录、最大最小⑥. 第三部分 - 页目录⑦. 第三部分 - 页面头部⑧. 从数据页角度看B树⑨. 区、段和表、碎片区 ①. 页的概述、大小 ①. 数据库的存储结构&…

云原生:10分钟了解一下Kubernetes架构

Kubernetes&#xff0c;作为当今容器编排技术的事实标准&#xff0c;以其强大的功能和灵活的架构设计&#xff0c;在全球范围内得到了广泛的应用和认可。本文将深入简出地探讨Kubernetes的核心架构&#xff0c;帮助大家了解Kubernetes&#xff0c;为今后的高效的学习打下良好的…

计算机网络 Cisco虚拟局域网划分

一、实验内容 1、分别把交换机命名为SWA、SWB 2、划分虚拟局域网 valn &#xff0c;并将端口静态划分到 vlan 中 划分vlan 方法一&#xff1a;在全局模式下划分vlan&#xff0c;在SWA交换机上创建三个vlan&#xff0c;分别为vlan2&#xff0c;vlan3&#xff0c;vlan4。 方…

1.初识Docker与容器

初识Docker与容器 文章目录 初识Docker与容器1、什么是DockerDocker架构 2、为什么使用DockerDocker容器虚拟化的好处Docker与虚拟机比较Docker为什么快 1、什么是Docker Docker是基于Go语言实现的开源容器项目。Docker是为解决了运行环境和配置问题的软件容器&#xff0c;方便…

24.4.11-13C语言学习笔记|函数、部分结构体【未完待续】

巴拉巴拉~~~哭死&#xff0c;学习啊啊啊啊&#xff0c;学校课好多&#xff0c;只能半夜学了 4.2函数名--特殊的地址&#xff1a; void fun(int a){ int aa1&#xff1b; printf("%d"&#xff0c;a); return a&#xff1b; } 指针函数&#xff1f;&#xff1f; void …

(五)C++自制植物大战僵尸游戏LoadingScene的实现讲解

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/xjvbb 一、类介绍 游戏启动后就会立即切换到游戏加载场景中。只有游戏资源文件加载完成后&#xff0c;才能进入游戏。Loadingscene类继承Cocos2d-x中的Scene父类&#xff0c;表明Loadingscene是一个场景类。切换到Loadi…

Mathorcup 甲骨文识别

本资源主要包含第2-4问&#xff0c;第一问直接使用传统图像处理即可&#xff0c;需要有很多步骤&#xff0c;这一步大家自己写就行。 2 第2问&#xff0c;甲骨文识别 2.1 先处理源文件 原文件有jpg和json文件&#xff0c;都在一个文件夹下&#xff0c;需要对json文件进行处理…

大数据存储解决方案和处理流程——解读大数据架构(四)

文章目录 前言数据存储解决方案数据集市运营数据存储&#xff08;Operational Data Store&#xff09;数据中心 数据处理数据虚拟化和数据联合虚拟化作为 ETL 或数据移动的替代品数据目录数据市场 前言 在数字时代&#xff0c;数据已成为公司的命脉。但是&#xff0c;仅仅拥有…

读《AI营销画布》品牌企业成长的逻辑(四)

前言 曾几何时&#xff0c;为了销售和品牌这两个扯的一世不可开交&#xff0c;也因为这个在企业里&#xff0c;形成了二个主张派&#xff0c;一派是以为销售为目标&#xff1b;一派是以品牌为目标。最后&#xff0c;&#xff0c;&#xff0c;&#xff0c;也就形成了不同的意见&…

c# .net 香橙派 Orangepi GPIO高低电平、上升沿触发\下降沿触发 监听回调方法

c# .net 香橙派GPIO高低电平、上升沿触发\下降沿触发 监听回调方法 通过gpio readall 查看 gpio编码 这里用orangepi zero3 ,gpio= 70为例 当gpio 70 输入高电平时,触发回调 c# .net 代码 方法1: Nuget 包 System.Device.Gpio ,微软官方库对香橙派支持越来越好了,用得…

学习JavaEE的日子 Day38 网络编程

Day38 网络编程(了解即可) 1. 计算机网络 2. 网络编程 实现多台计算机之间实现数据的共享和传递&#xff0c;网络应用程序主要组成为&#xff1a;网络编程IO流多线程 3. 网络模型 两台计算机之间的通信是根据什么规则来走的(OSI & TCP/IP) 此处简单了解该模型就行《TCP/IP…

Windows瘦客户机系统默认英文?一招改成中文界面

前言 最近发现有很多小伙伴给电脑安装了Windows瘦客户机系统&#xff0c;但开机之后发现系统是英文的&#xff0c;看都看不懂。 今天就给小伙伴们带来更改Windows Thin系统语言的办法。 首先&#xff0c;咱们都知道&#xff0c;更改系统显示语言基本上都是在系统设置或者控制…

Java——类和对象

目录 一.类定义和使用 1.简单认识类 2.类的定义格式 3.注意事项 二.课堂练习 1.定义一个狗类 2.定义一个学生类 3.注意事项&#xff1a; 三.类的实例化 1.什么是实例化 2.注意事项 3.类和对象的说明 四.this引用 1.为什么要有this引用 2.什么是this引用 五.对…

第16章 数据管理组织与角色期望知识点梳理

第16章 数据管理组织与角色期望知识点梳理&#xff08;附带页码&#xff09; ◼ 数据管理和数据治理组织需要足够灵活&#xff0c;才能在不断发展的环境中有效地工作。意识、所有权和问责制度是激励和吸引人们参加数据管理积极性、政策和流程的关键。P432 ◼ 如何了解组织的企…

【Docker】docker原理及使用-1

Docker目录 1️⃣概念2️⃣使用容器的好处2️⃣docker和普通软件启动方式的区别2️⃣docker和传统虚拟机的区别 1️⃣下载安装2️⃣安装步骤 1️⃣必须要掌握的核心概念1️⃣命令2️⃣例子2️⃣练习题目2️⃣进入一下python环境(简洁) 1️⃣解释一下 redis1️⃣docker底层隔离机…

AI大模型探索之路-应用篇12:AI大模型应用之向量数据库选型

目录 前言 一、什么是向量数据库&#xff1f; 二、向量数据库的应用场景 1. 图像检索 2. 推荐系统 3. 自然语言处理 三、向量数据库在AI大模型中的应用 1. 训练数据的索引和检索 2. 特征存储和管理 3. 模型中间结果的存储 4. 长上下文的记录和检索 5. 本地知识库的构…