【Canvas与艺术】蓝波纹白底黄星徽章

news2024/9/22 21:37:15

【成图】

【代码】

<!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 onload="init();">
        <div class="centerlize">
            <canvas id="myCanvas" width="12px" height="12px" style="border:1px dotted black;">
                如果看到这段文字说您的浏览器尚不支持HTML5 Canvas,请更换浏览器再试.
            </canvas>
        </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){
		//sleep(100);
		window.requestAnimationFrame(animate);   
    }
}

// 舞台类
function Stage(){
	// 初始化
	this.init=function(){
		
	}

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

	// 画背景
	this.paintBg=function(ctx){
		ctx.clearRect(-WIDTH/2,-HEIGHT/2,WIDTH,HEIGHT);// 清屏	
	}

	// 画前景
	this.paintFg=function(ctx){
		// 白底
		ctx.fillStyle = "white";
		ctx.fillRect(-WIDTH/2,-HEIGHT/2,WIDTH,HEIGHT);

		// 径向渐变红色缎带
		var gnt=ctx.createRadialGradient(0,0,0,0,0,WIDTH/2);
		gnt.addColorStop(0.75,"rgb(242,91,82)");
		gnt.addColorStop(1,"rgb(108,40,41)");
		ctx.fillStyle = gnt;
		const H=60;
		ctx.fillRect(-WIDTH/2,-H,WIDTH,2*H);

		// 波浪纹
		ctx.save();
        var arr=createWaveCircleArray(64,160,16);
        ctx.beginPath();
        for(var i=0;i<arr.length-2;i+=2){
            var pt1=arr[i];
            var pt2=arr[i+1];// 控制点
            var pt3=arr[i+2];            
            ctx.lineTo(pt1.x,pt1.y);
            ctx.quadraticCurveTo(pt2.x,pt2.y,pt3.x,pt3.y);
        }
        ctx.closePath();
        ctx.lineWidth=8;
        ctx.strokeStyle="rgb(226,235,242)";
		ctx.shadowOffsetX=0;
		ctx.shadowOffsetY=8;
		ctx.shadowColor="rgb(108,108,108)";
		ctx.shadowBlur=2;
        ctx.stroke();
		ctx.restore();
        ctx.fillStyle="rgb(22,51,85)";
        ctx.fill();

		// 红圈白底
		ctx.fillStyle="rgb(236,90,77)";
		ctx.beginPath();
		ctx.arc(0,0,136,0,Math.PI*2,false);
		ctx.closePath();
		ctx.fill();
		ctx.fillStyle="white";
		ctx.beginPath();
		ctx.arc(0,0,130,0,Math.PI*2,false);
		ctx.closePath();
		ctx.fill();
		
		// 上半圈文字
        var words="CONGRATULATIONS";
        var arr=words.split("");
        for(var i=0;i<arr.length;i++){
            var letter=arr[i];
            var theta=i*Math.PI/180*8.5+Math.PI+Math.PI/180*32;
            var x=96*Math.cos(theta);
            var y=96*Math.sin(theta);

            ctx.save();
            ctx.translate(x,y);
            ctx.rotate(theta+Math.PI/2);
            ctx.scale(1,1.2);
            ctx.textBaseline="bottom";
            ctx.textAlign="center";
            ctx.font = "18px Stencil Std";
            ctx.fillStyle="rgb(22,51,85)";
            ctx.fillText(letter,0,0);
            ctx.restore();
        }

		// 下半圈文字
        var words="CERTIFICATE";
        var arr=words.split("");
        for(var i=0;i<arr.length;i++){
            var letter=arr[i];
            var theta=-i*Math.PI/180*8.5+Math.PI-Math.PI/180*46;
            var x=124*Math.cos(theta);
            var y=124*Math.sin(theta);

            ctx.save();
            ctx.translate(x,y);
            ctx.rotate(theta-Math.PI/2);
            ctx.scale(1,1.2);
            ctx.textBaseline="bottom";
            ctx.textAlign="center";
            ctx.font = "18px Stencil Std";
            ctx.fillStyle="rgb(22,51,85)";
            ctx.fillText(letter,0,0);
            ctx.restore();
        }

		// 右侧三小星
		for(var i=0;i<3;i++){
			var theta=i*Math.PI/12-Math.PI/20;
			var pt=createPt(110*Math.cos(theta),110*Math.sin(theta));
			draw5Star(ctx,pt.x,pt.y,10);
			ctx.fillStyle="rgb(245,175,54)";
			ctx.fill();
		}

		// 左侧三小星
		for(var i=0;i<3;i++){
			var theta=i*Math.PI/12+Math.PI-Math.PI/20*2.5;
			var pt=createPt(110*Math.cos(theta),110*Math.sin(theta));
			draw5Star(ctx,pt.x,pt.y,10);
			ctx.fillStyle="rgb(245,175,54)";
			ctx.fill();
		}
		
		// 一圈辉光
		var r=84;
		var R=r+8;
		var N=120;
		for(var i=0;i<N;i++){
			var theta=Math.PI*2/N*i;
			var a=createPt(r*Math.cos(theta),r*Math.sin(theta));
			var b=createPt(R*Math.cos(theta),R*Math.sin(theta));
			
			ctx.lineWidth=2;
			ctx.strokeStyle="rgb(247,220,55)";
			ctx.beginPath();
			ctx.moveTo(a.x,a.y);
			ctx.lineTo(b.x,b.y);
			ctx.stroke();
		}

		// 蓝底圈
		ctx.fillStyle="rgb(22,51,85)";
		ctx.beginPath();
		ctx.arc(0,0,74,0,Math.PI*2,false);
		ctx.closePath();
		ctx.fill();

		// 尖刺
		var r=64;
		var n=36;
		for(var i=0;i<n;i++){
			var theta=Math.PI*2/n*i;
			var a=createPt(r*Math.cos(theta),r*Math.sin(theta));
			var b=createPt(a.x+r/Math.cos(Math.PI/48)*Math.cos(theta+Math.PI-Math.PI/48),a.y+r/Math.cos(Math.PI/48)*Math.sin(theta+Math.PI-Math.PI/48));
			var c=createPt(a.x+r/Math.cos(Math.PI/48)*Math.cos(theta+Math.PI+Math.PI/48),a.y+r/Math.cos(Math.PI/48)*Math.sin(theta+Math.PI+Math.PI/48));

			ctx.beginPath();
			ctx.moveTo(a.x,a.y);
			ctx.lineTo(b.x,b.y);
			ctx.lineTo(c.x,c.y);			
			ctx.closePath();
			ctx.fillStyle="rgb(74,95,124)";
			ctx.fill();
		}

		// 中心的黄色五角星
		var N=5;// 角个数
		var R=25;// 内径
		for(var i=0;i<N;i++){
			var theta=Math.PI*2/N*i-Math.PI/10*3;
			var a=createPt(R*Math.cos(theta),R*Math.sin(theta));
			
			var r=R*Math.sin(Math.PI/10*2)/Math.sin(Math.PI/10);
			var angle=theta+Math.PI/10*3;
			var b=createPt(a.x+r*Math.cos(angle),a.y+r*Math.sin(angle));
					
			// 填充上三角形
			ctx.fillStyle="rgb(245,175,54)";
			ctx.beginPath();
			ctx.moveTo(a.x,a.y);
			ctx.lineTo(b.x,b.y);
			ctx.lineTo(0,0);
			ctx.closePath();
			ctx.fill();

			angle=theta+Math.PI/10*4;
			var c=createPt(R*Math.cos(angle),R*Math.sin(angle));

			// 填充下三角形
			ctx.fillStyle="rgb(247,220,55)";
			ctx.beginPath();
			ctx.moveTo(0,0);			
			ctx.lineTo(b.x,b.y);
			ctx.lineTo(c.x,c.y);
			ctx.closePath();
			ctx.fill();
		}

		writeText(ctx,WIDTH/2-30,HEIGHT/2-5,"逆火原创","8px consolas","lightgrey");// 版权
	}
}

/*--------------------------------------------------
函数:绘制正五角星的推荐画法
ctx:绘图上下文
x:五角星中心横坐标
y:五角星中心纵坐标
R:五角星中心到顶点的距离
---------------------------------------------------*/
function draw5Star(ctx,x,y,R){
    var r=R*Math.sin(Math.PI/10)/Math.sin(Math.PI/10*7);
    
    var arr=[0,0,0,0,0,0,0,0,0,0];

    // 顶五点
    for(var i=0;i<5;i++){
        var theta=i*Math.PI/5*2-Math.PI/10;
        var x1=R*Math.cos(theta)+x;
        var y1=R*Math.sin(theta)+y;
        arr[i*2]=createPt(x1,y1);
    }

    // 内五点
    for(var i=0;i<5;i++){
        var theta=i*Math.PI/5*2+Math.PI/10;
        var x1=r*Math.cos(theta)+x;
        var y1=r*Math.sin(theta)+y;
        arr[i*2+1]=createPt(x1,y1);
    }

    ctx.beginPath();
    for(var i=0;i<arr.length;i++){
        ctx.lineTo(arr[i].x,arr[i].y);
    }
    ctx.closePath();
}

//--------------------------------------------------
// 函数:创建波浪式环形需要的数组
// n:浪头峰谷个数
// radius:环形半径
// waveHeight:浪高
// 返回:包含浪高中低点坐标的数组
//--------------------------------------------------
function createWaveCircleArray(n,radius,waveHeight){
    var arr=[];

    const LEN=n+2;// 数组长度比浪头峰谷数多两个以在绘图时形成闭环    
    for(var i=0;i<LEN;i++){
        var theta=i*Math.PI*2/n;
        var r=radius+Math.sin(Math.PI/2*i)*waveHeight;// 造成涨落
        var pt={};
        pt.x=r*Math.cos(theta);
        pt.y=r*Math.sin(theta);
        arr.push(pt);
    }

    return arr;
}


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

/*----------------------------------------------------------
函数:延时若干毫秒
milliseconds:毫秒数
----------------------------------------------------------*/
function sleep(milliSeconds) {
	const date = Date.now();
	let currDate = null;
	while (currDate - date < milliSeconds) {
		currDate = Date.now();
	} 
}

/*----------------------------------------------------------
函数:书写文字
ctx:绘图上下文
x:横坐标
y:纵坐标
text:文字
font:字体
color:颜色
----------------------------------------------------------*/
function writeText(ctx,x,y,text,font,color){
	ctx.save();
	ctx.textBaseline="bottom";
	ctx.textAlign="center";
	ctx.font = font;
	ctx.fillStyle=color;
	ctx.fillText(text,x,y);
	ctx.restore();
}

/*-------------------------------------------------------------
五十七载如一梦
举国沦亡缘汉城
龙游浅水勿自弃
终有扬眉吐气天
--北洋舰队老人萨镇冰在得知志愿军攻入汉城作
--------------------------------------------------------------*/
//-->
</script>

END

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《系统架构设计师教程(第2版)》第13章-层次式架构设计理论与实践-04-数据访问层设计

文章目录 1. 五种数据访问模式1.1 在线访问1.2 DAO1.3 DTO1.4 离线数据模式1.5 对象/关系映射 (O/R Mapping) 2. 工厂方法模式在数据访问层应用3 ORM、Hibernate与CMP2.0设计思想3.1 ORM3.2 Hibernate1&#xff09;概述2&#xff09; Hibernate的架构&#xff08;2023年的考题&…

SpringBoot统一功能处理——统一数据返回格式

目录 一、简单使用 二、存在的问题描述 三、优点 一、简单使用 统一的数据返回格式使用 ControllerAdvice 和 ResponseBodyAdvice 的方式实现 ControllerAdvice 表示控制器通知类。 添加类 ResponseAdvice , 实现 ResponseBodyAdvice 接口&#xff0c;并在类上添加 …

【jQuery】入门学习篇

文章目录 一、前言&#x1f680;&#x1f680;&#x1f680;二、jQuery简介及使用详解&#xff1a;☀️☀️☀️2.1 jQuery简介2.2 引入jQuery① 第一种引入方式&#xff1a;直接路径引入② 第二种引入方式&#xff1a;使用第三方CDN 后序还在更新中~~~三、总结&#xff1a;&am…

C++_基本语法笔记_类和对象

对于有Java基础的思想不过多记录&#xff0c;仅看语法 创建和封装对象 类似Java中的set操作&#xff0c;可以写一个赋值操作用于给实例化对象赋属性值 三种权限&#xff1a;public &#xff0c; protect &#xff0c;private Class和Struct区别 Struct默认为public权限cla…

SpringBoot统一功能处理——拦截器

目录 一、什么是拦截器&#xff1f; 二、拦截器使用 2.1 定义拦截器 2.2 注册配置拦截器 三、拦截器详解 3.1 拦截器的拦截路径配置 3.2 拦截器执行流程 一、什么是拦截器&#xff1f; 拦截器是Spring框架提供的核心功能之一, 主要用来拦截用户的请求, 在指定方法前后,…

C语言 | Leetcode C语言题解之第332题重新安排行程

题目&#xff1a; 题解&#xff1a; char* id2str[26 * 26 * 26];int str2id(char* a) {int ret 0;for (int i 0; i < 3; i) {ret ret * 26 a[i] - A;}return ret; }int cmp(const void* _a, const void* _b) {int **a (int**)_a, **b (int**)_b;return (*b)[0] - (*…

python网络爬虫使用代理

Python网络爬虫使用代理的实用指南 在网络爬虫的开发过程中&#xff0c;使用代理是一个非常重要的环节。代理不仅可以帮助爬虫绕过反爬虫机制&#xff0c;还能保护开发者的隐私。本文将介绍如何在Python中使用代理进行网络爬虫&#xff0c;包括基本的设置和示例代码。 1. 代理…

手机短视频素材网站有哪些啊?手机视频素材库网站分享

在当今的数字时代&#xff0c;智能手机与社交媒体平台的融合推动了手机短视频的兴起。这种形式的媒体已经渗透到我们的日常生活中&#xff0c;无论是作为娱乐手段、教育工具还是商业推广手段&#xff0c;优质的短视频都具有极高的吸引力和广泛的应用价值。因此&#xff0c;选择…

『 C++ 』智能指针 ( 万字梳理 )

文章目录 智能指针概念内存泄漏的危害RAII与智能指针智能指针的赋值auto_ptr 管理权转移auto_ptr 的对象悬空问题 unique_ptr 防拷贝unique_ptr 简单实现 shared_ptr 引用计数shared_ptr 简单实现shared_ptr 的循环引用问题与 weak_ptr 智能指针的自定义删除器 智能指针概念 智…

【独家原创】基于NRBO-Transformer多特征分类预测【24年新算法】 (多输入单输出)Matlab代码

【独家原创】NRBO-Transformer分类 Matlab代码 基于牛顿拉夫逊优化算法优化Transformer的数据分类预测&#xff0c;Matlab代码&#xff0c;可直接运行&#xff0c;适合小白新手 NRBO优化的超参数为&#xff1a;自注意力机制中的头数、正则化系数、初始化学习率 1.程序已经调试…

《知识点扫盲 · Redis 分布式锁》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

数据库索引设计原则

1. 概述 索引是优化数据库性能最重要的工具之一。但是&#xff0c;创建过多的索引或索引错误的列也会对性能产生负面影响。因此&#xff0c;在设计索引时遵循一定的原则很重要。 2. 原则A - 根据工作负载创建索引 创建高效索引最重要的原则是根据您的工作负载而不是表结构创…

数据库连接池的深入学习

为什么需要数据库连接池&#xff1f; 正常操作数据库需要对其进行连接&#xff0c;访问数据库&#xff0c;执行sql语句&#xff0c;断开连接。 创建数据库连接是一个昂贵的过程&#xff0c;在高并发的情况下&#xff0c;频繁的创建数据库的连接可能会导致数据库宕机。 有了连…

Leetcode JAVA刷刷站(8)字符串转换整数

一、题目概述 二、思路方向 要实现这个功能&#xff0c;我们可以遵循以下步骤来编写 myAtoi 函数&#xff1a; 去除前导空格&#xff1a;使用循环或字符串的 trim() 方法&#xff08;虽然直接操作字符串更高效的方式是使用循环&#xff09;。检查符号&#xff1a;记录第一个非…

TGANet部分复现

Kvasir-SEG复现结果 M e t h o d m I o U m D S C R e c a l l P r e c i s i o n F 2 P r a N e t − − − − − − 0.9663704860609511 − − T G A N e t 0.8331 0.8982 0.9132 − − 0.9029 \begin{array}{lccccr} Method&mIoU&mDSC&Recall&Precision&a…

5、Linux : 网络相关

OSI七层网络模型 TCP/IP四层 概念模型 对应网络协议 应用层&#xff08;Application&#xff09; HTTP、TFTP, FTP, NFS, WAIS、 表示层&#xff08;Presentation&#xff09; 应用层 Telnet, Rlogin, SNMP, Gopher 会话层&#xff08;Session&#xff09; SMTP…

ICETEK-DM6437-AICOM——CPU定时器及直流电机控制中断控制

一、设计目的&#xff1a; 1.1 CPU定时器程序设计&#xff1b; 1.2 2直流电机程序设计&#xff1b; 1.3 外中断。 二、设计原理&#xff1a; 2.1 定时器的控制&#xff1a; 在DM6437&#xff08;是一种数字信号处理器&#xff0c;DSP&#xff09;上使用其内部定时器和中断来…

设计模式-动态代理模式

目录 什么是代理模式&#xff1f; 为什么要用代理模式&#xff1f; 有哪几种代理模式&#xff1f; 动态代理&#xff08;jdk自带&#xff09;&#xff1a; 动态代理&#xff08;第三方库-cglib&#xff09;&#xff1a; 什么是代理模式&#xff1f; 代理模式给某一个对象提供…

Windows10不能直接拖拽文件到微信或者钉钉的解决办法【玖毅网】

不知道从何时起,微信、QQ和钉钉等相关软件,无法拖拽文件到对话窗口,拖拽的时候显示一个红色图标,可能是上次更新win之后导致的,所以嘛,系统真的不能设置自动更新,说不准哪些更新就把原设置覆盖或者关闭了,哎,吃一堑长一智吧,赶紧关闭自动更新,emmmm我在说我自己啊。…

日撸Java三百行(day17:链队列)

目录 一、队列基础知识 1.队列的概念 2.队列的实现 二、代码实现 1.链队列创建 2.链队列遍历 3.入队 4.出队 5.数据测试 6.完整的程序代码 总结 一、队列基础知识 1.队列的概念 今天我们继续学习另一个常见的数据结构——队列。和栈一样&#xff0c;队列也是一种操…