canvas-getContext("2d")实例1

效果图:

html+js代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>bezierCurveTo</title>
    <style>
        .canvas{
            display: inline-block;
            float: left;
            width: 300px;
            margin: 10px;
        }
        canvas {
            border:1px solid #d3d3d3;
        }
    </style>
</head>
<body>
    <div class="canvas">
        <div>------------线条样式------------</div>
        <canvas id="myCanvas1" width="300" height="300"></canvas>
    </div>

    <div class="canvas">
        <div>------------线条样式------------</div>
        <canvas id="myCanvas2" width="300" height="300"></canvas>
    </div>

     <div class="canvas">
        <div>-------手动调整贝塞尔曲线--------</div>
        <canvas id="myCanvas3" width="300" height="300"></canvas>
    </div>

     <div class="canvas">
        <div>------------粒子特效-----------</div>
        <canvas id="myCanvas4" width="300" height="300"></canvas>
        <input type="text" id='textNode' placeholder="请输入要粒子化的文字" />
        <button id='submiteBtn'>提交</button>
    </div>
    <script>
        var myCanvas1 = document.getElementById('myCanvas1');
        var ctx1 = myCanvas1.getContext('2d');

        var myCanvas2 = document.getElementById('myCanvas2');
        var ctx2 = myCanvas2.getContext('2d');

        let x = 0, y = 300, h = 0;      

        function drawBezierCurveTo(ctx, x, y, h){
            ctx.beginPath();
            ctx.fillStyle = 'black';
            ctx.moveTo(90, 0);
            ctx.lineTo(150, 300);
            ctx.lineTo(30, 300);
            ctx.closePath();
            ctx.strokeStyle = 'blue';
            ctx.fill();
            ctx.stroke();
            ctx.globalCompositeOperation = 'source-atop';
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.strokeStyle="red";
            ctx.quadraticCurveTo(x + 15, y + 15, x + 30, y);
            ctx.quadraticCurveTo(x + 45, y - 15, x + 60, y);
            ctx.quadraticCurveTo(x + 75, y + 15, x + 90, y);
            ctx.quadraticCurveTo(x + 105, y - 15, x + 120, y);
            ctx.quadraticCurveTo(x + 135, y + 15, x + 150, y);
            ctx.quadraticCurveTo(x + 165, y - 15, x + 180, y);
            ctx.quadraticCurveTo(x + 195, y + 15, x + 210, y);
            ctx.lineTo(x + 210, y + h);
            ctx.lineTo(x, y + h);
            ctx.closePath();
            ctx.fillStyle = 'pink';
            ctx.fill();
            ctx.stroke();

            ctx.beginPath();
            ctx.font = "20px Georgia";
            ctx.textAlign = 'center';
            ctx.fillStyle = 'white';
            ctx.fillText((h / 300).toFixed(2) * 100 + '%', 90, 150);
        }
        
        function totalAnimate(){
            let timer = setInterval(()=>{
                drawBezierCurveTo(ctx1, x, y, h);
                x -= 1;
                y -= 1;
                h += 1;
                if (y < 20){
                    clearInterval(timer);
                    timer = null;
                }
                if(x === -60){
                    x = 0
                }
                
            },20);
        }

        totalAnimate();
        // drawBezierCurveTo(x, y);

        // drawText('hello world') ;

        function drawText(text) {
            ctx1.beginPath();
            ctx1.font = '30px Arial';
            ctx1.textAlign="center";
            ctx1.fillStyle = 'red';
            ctx1.globalCompositeOperation = 'source-over';
            ctx1.fillText(text, 150, 150);
        }

        // -----------------------------------canvas属性划分-------------------------------\
        function drawLine(ctx, sx,sy, ex, ey, color, lineWidth){
            ctx.beginPath();
            ctx.moveTo(sx, sy);
            ctx.lineTo(ex, ey);
            ctx.lineWidth = lineWidth;
            ctx.strokeStyle = color;
            ctx.stroke();
        }

        drawLine(ctx2, 20, 20, 275, 20, 'red', 5);
        drawLine(ctx2, 20, 40, 275, 40, 'pink', 5);
        

        function drawRect (){
            ctx2.clearRect(-30, -30, 60, 60);
            ctx2.beginPath();
            ctx2.lineWidth = 1;
            ctx2.strokeStyle = 'red';
            ctx2.moveTo(-20, -20);
            ctx2.lineTo(20, -20);
            ctx2.lineTo(0, 0);
            ctx2.closePath();
            ctx2.fillStyle = 'red';
            ctx2.fill();
            ctx2.stroke();

            ctx2.beginPath();
            ctx2.lineWidth = 1;
            ctx2.strokeStyle = 'yellow';
            ctx2.moveTo(20, -20);
            ctx2.lineTo(20, 20);
            ctx2.lineTo(0, 0);
            ctx2.closePath();
            ctx2.fillStyle = 'yellow';
            ctx2.fill();
            ctx2.stroke();


            ctx2.beginPath();
            ctx2.lineWidth = 1;
            ctx2.strokeStyle = 'pink';
            ctx2.moveTo(20, 20);
            ctx2.lineTo(-20, 20);
            ctx2.lineTo(0, 0);
            ctx2.closePath();
            ctx2.fillStyle = 'pink';
            ctx2.fill();
            ctx2.stroke();


            ctx2.beginPath();
            ctx2.lineWidth = 1;
            ctx2.strokeStyle = 'white';
            ctx2.moveTo(-20, 20);
            ctx2.lineTo(-20, -20);
            ctx2.lineTo(0, 0);
            ctx2.fillStyle = 'white';
            ctx2.fill();
            ctx2.closePath();
            ctx2.stroke();

            ctx2.beginPath();
            ctx2.strokeStyle = 'black';
            ctx2.arc(0,0,20,0,2*Math.PI);
            ctx2.stroke();
        }

        // ctx2.translate(40,80);

        let angle = 0;
        // drawRect();
        ctx2.translate(40,60);
        let timer2 = setInterval(()=>{
            drawRect();
            ctx2.rotate(4 * Math.PI / 180);
            angle += 5;
            if (angle > 720) {
                clearInterval(timer2);
                timer2 = null;
            }
        },30);


        // 手动调整贝塞尔曲线
        class Canvas03 {
            constructor(id){
                let idNode = document.getElementById(id);
                this.id = idNode;
                this.width = idNode.width;
                this.height = idNode.height;
                this.ctx = idNode.getContext('2d');
                this.top = idNode.getBoundingClientRect().top;
                this.left = idNode.getBoundingClientRect().left;
                this.startX = 60;
                this.startY = 100;
                this.startText = '';

                this.endX = 240;
                this.endY = 100;
                this.endText = '';

                this.controlX = 150;
                this.controlY = 150;
                this.controlText = '';

                this.pointName = '';

                this.mousemovefn = this.mousemovefn.bind(this);
                this.mousedownfn = this.mousedownfn.bind(this);
                this.mouseupfn = this.mouseupfn.bind(this);
                this.getMousePos = this.getMousePos.bind(this);
                this.sampleMousemovefn = this.sampleMousemovefn.bind(this);
            }

            init() {
                this.ctx.clearRect(0,0,this.width,this.height);
                this.drawLine();
                this.drawthreeArc();
                this.dragFn();
            }

            // 绘制贝塞尔曲线 以及控制点到贝塞尔曲线两端的直线
            drawLine() {
                let {startX, startY, endX, endY, controlX, controlY} = this;
                this.ctx.beginPath();
                this.ctx.moveTo(startX, startY);
                this.ctx.quadraticCurveTo(controlX, controlY, endX, endY);
                this.ctx.stroke();
                this.ctx.beginPath();
                this.ctx.moveTo(startX, startY);
                this.ctx.lineTo(controlX, controlY);
                this.ctx.strokeStyle = 'pink';
                this.ctx.stroke();

                this.ctx.beginPath();
                this.ctx.moveTo(endX, endY);
                this.ctx.lineTo(controlX, controlY);
                this.ctx.strokeStyle = 'pink';
                this.ctx.stroke();
            }

            // 控制点增加圆环样式
            drawArc(x, y, r, lineWidth) {
                this.ctx.beginPath();
                this.ctx.strokeStyle = "#999";
                this.ctx.arc(x,y,r,0,2*Math.PI);
                if (lineWidth) this.ctx.lineWidth = lineWidth;
                this.ctx.fillText("("+ x +","+ y +")", x + 10, y);
                this.ctx.stroke();
            }

            // 绘制三个控制点 直线的开始点 结束点 贝塞尔曲线的控制点
            drawthreeArc(){
                let {startX, startY, endX, endY, controlX, controlY} = this;
                this.drawArc(startX, startY, 6);
                this.drawArc(endX, endY, 6);
                this.drawArc(controlX, controlY, 6);
            }

            //获取鼠标在画布中的绝对位置
            getMousePos(evt){
                let rect = this.id.getBoundingClientRect();
                return {
                    x: evt.clientX - rect.left * (this.width / rect.width),
                    y: evt.clientY - rect.top * (this.height / rect.height)
                }
            }

            // 点被选中后的鼠标移动事件
            mousemovefn(evt){
                let {x, y} = this.getMousePos(evt);
                let {top, left} = this;
                let {startX, startY, endX, endY, controlX, controlY} = this;
                if (x > controlX - 10 && y > controlY - 10 && x < controlX + 10 && y < controlY + 10){
                    this.pointName = 'control';
                    this.id.style.cssText = "cursor: pointer;";
                    this.drawArc(controlX, controlY, 8, 1);
                    this.controlX = evt.clientX - left;
                    this.controlY = evt.clientY - top;
                    this.avoidStartAndEndPointOverlay();
                    this.init();
                }else {
                    this.pointName = '';
                    this.id.style.cssText = "cuosor: default;";
                    this.init();
                }

                if (x > startX - 10 && y > startY - 10 && x < startX + 10 && y < startY + 10){
                    this.pointName = 'start';
                    this.id.style.cssText = "cursor: pointer;";
                    this.drawArc(startX, startY, 8, 1);
                    this.startX = evt.clientX - left;
                    this.startY = evt.clientY - top;
                    this.avoidStartAndEndPointOverlay();
                    this.init();
                }else {
                    this.pointName = '';
                    this.id.style.cssText = "cuosor: default;";
                    this.init();
                }

                if (x > endX - 10 && y > endY - 10 && x < endX + 10 && y < endY + 10){
                    this.pointName = 'end';
                    this.id.style.cssText = "cursor: pointer;";
                    this.drawArc(endX, endY, 8, 1);
                    this.endX = evt.clientX - left;
                    this.endY = evt.clientY - top;
                    this.avoidStartAndEndPointOverlay();
                    this.init();
                }else {
                    this.pointName = '';
                    this.id.style.cssText = "cuosor: default;";
                    this.init();
                }
            }

            // 避免三个控制点位置重叠
            avoidStartAndEndPointOverlay(){
                let {startX, startY, endX, endY, controlX, controlY} = this;
                if (Math.abs(startX - endX) < 5 || Math.abs(startY - endY) < 5) {
                    if (this.pointName === 'start') {
                        this.startX += 5;
                        this.startY += 5;
                    }
                    if (this.pointName === 'end') {
                        this.endX += 5;
                        this.endY += 5;
                    }
                }

                if (Math.abs(startX - controlX) < 5 || Math.abs(startY - controlY) < 5) {
                    if (this.pointName === 'start') {
                        this.startX += 5;
                        this.startY += 5;
                    }
                    if (this.pointName === 'control') {
                        this.controlX += 5;
                        this.controlY += 5;
                    }
                }

                if (Math.abs(endX - controlX) < 5 || Math.abs(endY - controlY) < 5) {
                    if (this.pointName === 'end') {
                        this.endX += 5;
                        this.endY += 5;
                    }
                    if (this.pointName === 'control') {
                        this.controlX += 5;
                        this.controlY += 5;
                    }
                }
            }

            // 鼠标移动事件。当鼠标移动到控制点时控制点增加样式
            sampleMousemovefn(evt){
                let {x, y} = this.getMousePos(evt);
                let {top, left} = this;
                let {startX, startY, endX, endY, controlX, controlY} = this;
                if (x > controlX - 10 && y > controlY - 10 && x < controlX + 10 && y < controlY + 10){
                    this.id.style.cssText = "cursor: pointer;";
                    this.drawArc(controlX, controlY, 6, 1);
                }else {
                    this.id.style.cssText = "cuosor: default;";
                }

                if (x > startX - 10 && y > startY - 10 && x < startX + 10 && y < startY + 10){
                    this.id.style.cssText = "cursor: pointer;";
                    this.drawArc(startX, startY, 6, 1);
                }else {
                    this.id.style.cssText = "cuosor: default;";
                }

                if (x > endX - 10 && y > endY - 10 && x < endX + 10 && y < endY + 10){
                    this.id.style.cssText = "cursor: pointer;";
                    this.drawArc(endX, endY, 6, 1);
                }else {
                    this.id.style.cssText = "cuosor: default;";
                }
            }

            mousedownfn(){
                this.id.addEventListener("mousemove", this.mousemovefn, false);
            }

            mouseupfn(){
                this.id.removeEventListener("mousemove",this.mousemovefn, false);
                this.init();
            }

            // 圆点拖拽功能
            dragFn(){
                this.id.removeEventListener('mousemove', this.sampleMousemovefn, false);
                this.id.removeEventListener('mousedown', this.mousedownfn, false);
                this.id.removeEventListener('mouseup', this.mouseupfn, false);
                this.id.addEventListener("mousemove", this.sampleMousemovefn, false);
                this.id.addEventListener("mousedown", this.mousedownfn, false);
                this.id.addEventListener("mouseup", this.mouseupfn, false);
            }
        }

        const myCanvas3 = new Canvas03('myCanvas3');
        myCanvas3.init();



        // 粒子特效
        class ParticleEffects {
            constructor (){
                let myCanvas4 = document.getElementById('myCanvas4');
                let textNode = document.getElementById('textNode');
                let submiteBtn = document.getElementById('submiteBtn');
                this.myCanvas4 = myCanvas4;
                this.textNode = textNode;
                this.submiteBtn = submiteBtn;
                this.width = myCanvas4.width;
                this.height = myCanvas4.height;
                this.ctx = myCanvas4.getContext('2d');
                this.top = myCanvas4.getBoundingClientRect().top;
                this.left = myCanvas4.getBoundingClientRect().left;
                this.textValue = '❤️canvas';

                this.textBindEvent();
                this.submitBtnBindEvent();
            }

            init(){
                this.drawText();
            }

            // 在canvas上绘制文本
            drawText(){
                this.ctx.clearRect(0, 0, this.width, this.height);
                this.ctx.beginPath();
                this.ctx.textAlign = "center";
                this.ctx.font = '66px Arial';
                this.ctx.fillStyle = 'pink';
                this.ctx.fillText(this.textValue, 150, 150);
                this.ctx.stroke();
                this.canvsaToImage();
            }

            // 将canvas转成图片 然后再绘制图片
            canvsaToImage(){
                let img = new Image();
                img.src = this.myCanvas4.toDataURL('image/jepg');
                img.onload = ()=>{
                    this.ctx.drawImage(img, 0, 0);
                    let imageData = this.ctx.getImageData(0, 0, this.width, this.height);
                    let particleData = [];
                    // 反转颜色
                    let startX = 125, startY = 125;
                    for (var i=0, j = 1;i<imageData.data.length;i+=4){
                        let colorStr = imageData.data[i] + '' + imageData.data[i+1]+ imageData.data[i+2]+ imageData.data[i+3];
                        if (colorStr !== '0000') {
                            particleData.push({
                                x: j % this.width,
                                y: parseInt(j / this.width) + 1,
                                moveX: 0,
                                moveY: 0,
                                flutteMoveX: 0,
                                flutteMoveY: 0,
                                xStep: (j % this.width -( startX % 100 + 100)) / 10,
                                yStep: (parseInt(j / this.width) + 1 - (Math.floor(startX / 100) + 100)) / 10,
                                startX: startX % 100 + 100,
                                startY: Math.floor(startX / 100) + 100
                            });
                            startX++;
                        }
                        j++;
                    }
                    this.drawParticle(particleData);
                }
            }

            // 绘制粒子描绘出来的粒子
            drawParticle(particleDataArr){
                if (Object.prototype.toString.call(particleDataArr) === '[object Array]'){
                     // 增加飘动效果
                    this.ctx.clearRect(0, 0, this.width, this.height);
                    particleDataArr.map((item, index)=>{
                        let {startX, startY} = item;
                        this.ctx.beginPath();
                        this.ctx.arc(startX, startY, 2, 0, 2*Math.PI);
                        this.ctx.strokeStyle = 'pink';
                        this.ctx.stroke();
                    })

                    // 1s内粒子从矩形转成文字
                     this.timeout1 = setTimeout(()=>{
                        this.timer = setInterval(()=>{
                            this.ctx.clearRect(0, 0, this.width, this.height);
                            particleDataArr.map((item, index)=>{
                                if (index % 10 === 0) {
                                    let {x, y, moveX, moveY, xStep, yStep, startX, startY} = item;
                                    
                                    this.ctx.beginPath();
                                    this.ctx.arc(startX + moveX, startY + moveY, 2, 0, 2*Math.PI);
                                    this.ctx.strokeStyle = 'pink';
                                    this.ctx.stroke();
                                    item.moveX = moveX + xStep;
                                    item.moveY = moveY + yStep;
                                }
                            });
                        }, 100);
                        
                        this.timeout1 = setTimeout(()=>{
                            
                            clearInterval(this.timer);
                            clearTimeout(this.timeout1);
                            this.timer = null;
                            this.timeout1 = null;
                        }, 1000);
                    },100)

                    this.timeout2 = setTimeout(()=>{
                        this.timer = setInterval(()=>{
                            this.ctx.clearRect(0, 0, this.width, this.height);
                            particleDataArr.map((item, index)=>{
                                if (index % 10 === 0) {
                                    let {x, y, flutteMoveX, flutteMoveY, xStep, yStep} = item;

                                    if(flutteMoveX === 0 && flutteMoveY === 0) flutteMoveX = Math.floor(Math.random() * 11 - 5), flutteMoveY = Math.floor(Math.random() * 11 - 5);
                                    
                                    if(flutteMoveX >= -1 && flutteMoveX <= 1){

                                    }else {
                                        if(flutteMoveX >= 1) xStep = -1;
                                        if(flutteMoveX <= -1) xStep = 1;
                                    }
                                    if(flutteMoveY >= -1 && flutteMoveY <= 1){

                                    }else {
                                        if(flutteMoveY >= 1) yStep = -1;
                                        if(flutteMoveY <= -1) yStep = 1;
                                    }
                                    
                                    this.ctx.beginPath();
                                    this.ctx.arc(x + flutteMoveX, y + flutteMoveY, 2, 0, 2*Math.PI);
                                    this.ctx.strokeStyle = 'pink';
                                    this.ctx.stroke();
                                    item.flutteMoveX = flutteMoveX + xStep;
                                    item.flutteMoveY = flutteMoveY + yStep;
                                    item.xStep = xStep;
                                    item.yStep =  yStep;

                                }
                            });
                        }, 100);
                    }, 1350);
                        
                }
            }

            // 绘制飘动的粒子
            drawParticleFlutter(x, y){
                let moveX = 0, moveY = 0;
                setInterval
            }

            // 文本框绑定键盘事件
            textEvent (evt) {
                if(evt.keyCode === 13){
                    clearInterval(this.timer);
                    this.timer = null;
                    this.init();
                }else{
                    this.textValue = evt.target.value;
                }
            }
            textBindEvent (){
                this.textNode.addEventListener('keyup', this.textEvent.bind(this), false);
            }

            // 提交按钮绑定鼠标事件
            submiteBtnEvent(evt){
                this.textNode.removeEventListener('keydown', this.textEvent.bind(this), false);
                this.submiteBtn.removeEventListener('click', this.submiteBtnEvent.bind(this), false);
                this.init();
            }
            submitBtnBindEvent (){
                this.submiteBtn.addEventListener('click', (evt)=>{
                    clearInterval(this.timer);
                    clearTimeout(this.timeout1);
                    clearTimeout(this.timeout2);
                    this.timeout1 = null;
                    this.timeout2 = null;
                    this.timer = null;
                    this.init();
                }, false);
            }
        }

        let particleEffects = new ParticleEffects();
        particleEffects.init();


    </script>
</body>
</html>

猜你喜欢

转载自www.cnblogs.com/dadouF4/p/11733944.html