ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

用画布canvas画个爱心

2020-02-29 16:01:42  阅读:547  来源: 互联网

标签:canvas ctx cos 画布 var 画个 cv Math size


首先我们找一个爱心的方程式

 x=12*sin(t)-4*sin(3*t),y=13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t)

然后根据方程式绘制爱心,上代码:

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style type="text/css">
    body{
    overflow: hidden;
    margin: 0;
    }
    </style>
</head>
<body>
    <canvas id="cv">您的浏览器不兼容canvas</canvas>
    <script>
    var cv = document.getElementById("cv");
    var ctx = cv.getContext('2d');
    var width = cv.width = window.innerWidth;
    var height = cv.height = window.innerHeight;
    var percision = 100;





    class Heart {
        constructor(x, y, size) {
            this.x = x || Math.random() * width;
            this.y = y || Math.random() * height;
            this.size = size || Math.random() * 2 + 1;
            //this.rotate = (this.speedx / this.speedy) * 100; //旋转度数
            this.vertices = new Array();//存放爱心坐标数组
            for (var i = 0; i < percision; i++) {
                var t = Math.PI * 2 * (i / percision - 0.5);
                var tx = 12 * Math.sin(t) - 4 * Math.sin(3 * t);
                var ty = 13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t);
                this.vertices.push({ x: tx, y: -ty });
            }
        }
        draw() {
            ctx.translate(this.x, this.y); //偏移绘制原点
            ctx.beginPath(); //开始绘制
            //ctx.rotate(this.rotate); //旋转
            ctx.scale(this.size, this.size); //缩放
            this.vertices.forEach(element => {
                ctx.lineTo(element.x, element.y); //绘制轮廓
            });
            ctx.fillStyle = "red";//填充颜色
            ctx.closePath(); //结束绘制
            ctx.fill(); //填充轮廓
            ctx.restore(); //返回之前保存过的路径状态和属性
        }
    }
   new Heart(200,200,2).draw(); </script> </body> </html>

 

效果:

 

用爱心写一个动画:

var cv = document.getElementById("cv");
var ctx = cv.getContext('2d');
var width;
var height;
var percision = 100;
var hearts = new Array();

ctx.strokeStyle = "red";
ctx.shadowBlur = 25;
ctx.shadowColor = "hsla(0, 100%, 60%,0.5)";

//爱心方程式  x=12*sin(t)-4*sin(3*t),y=13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t)
//属性参考 https://www.w3school.com.cn/tags/html_ref_canvas.asp

function onResize(){
    width = cv.width = window.innerWidth;
    height = cv.height = window.innerHeight;
}
onResize();

class Heart {
    constructor(x, y, size) {
        this.x = x || Math.random() * width;
        this.y = y || Math.random() * height;
        this.size = size || Math.random() * 2 + 1;
        this.speedx = (Math.random() - 0.5) * 8 ; //x轴增量
        this.speedy = (Math.random() - 0.5) * 8 ; //y轴增量
        this.speedSize = Math.random() * 0.03 + 0.01; //size增量
        //this.rotate = (this.speedx / this.speedy) * 100; //旋转度数
        this.vertices = new Array();
        for (var i = 0; i < percision; i++) {
            var t = Math.PI * 2 * (i / percision - 0.5);
            var tx = 12 * Math.sin(t) - 4 * Math.sin(3 * t);
            var ty = 13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t);
            this.vertices.push({ x: tx, y: -ty });
        }
    }
    draw() {
        this.x += this.speedx;
        this.y += this.speedy;
        this.size -= this.speedSize;
        ctx.save(); //保存状态
        ctx.translate(-1000, this.y); //偏移绘制原点
        ctx.beginPath(); //开始绘制
        //ctx.rotate(this.rotate); //旋转
        ctx.scale(this.size, this.size); //缩放
        this.vertices.forEach(element => {
            ctx.lineTo(element.x, element.y); //绘制轮廓
        });
        ctx.globalAlpha = this.size; //设置透明度
        ctx.shadowBlur = Math.round((3 - this.size) * 10); //阴影模糊
        ctx.shadowColor = "hsla(0, 100%, 60%,0.5)"; //阴影颜色
        ctx.shadowOffsetX = this.x + 1000; //设置或返回阴影距形状的水平距离   用阴影绘制,本体藏在canvas之外
        ctx.globalCompositeOperation = "screen"; //设置或返回新图像如何绘制到已有的图像上
        ctx.closePath(); //结束绘制
        ctx.fill(); //填充轮廓
        ctx.restore(); //返回之前保存过的路径状态和属性
    }
}

function render(){
    requestAnimationFrame(render);

    if(hearts.length < 99){
        hearts.push(new Heart());
    }
    ctx.clearRect(0,0,width,height);

    hearts.forEach((element,i) => {
        element.draw();
        if(element.size < 0){
            hearts.splice(i,1);
        }
    })
}


window.requestAnimationFrame(render);
window.addEventListener("resize", onResize);
//告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。
//该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
//若你想在浏览器下次重绘之前继续更新下一帧动画,那么回调函数自身必须再次调用window.requestAnimationFrame()



var mouseMoved = false;
function onMove(e){
  mouseMoved = true;
  if(e.type === "touchmove"){
    hearts.push(new Heart(e.touches[0].clientX, e.touches[0].clientY));
    hearts.push(new Heart(e.touches[0].clientX, e.touches[0].clientY));
  }
  else{
    hearts.push(new Heart(e.clientX, e.clientY));
    hearts.push(new Heart(e.clientX, e.clientY));
  }
}

window.addEventListener("mousemove", onMove);
window.addEventListener("touchmove", onMove);

 

标签:canvas,ctx,cos,画布,var,画个,cv,Math,size
来源: https://www.cnblogs.com/sukeryy/p/12383383.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有