用畫布canvas畫個愛心


首先我們找一個愛心的方程式

 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.save(); 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);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM