最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • canvas-03

    正文概述 掘金(卡兹)   2021-03-19   547

    动画

    1、小球弹性运动

    <script>
        const canvas=document.getElementById('canvas');
        const [width,height]=[window.innerWidth,window.innerHeight];
        canvas.width=width;
        canvas.height=height;
        //画笔
        const  ctx=canvas.getContext('2d');
    
        //小球对象化
        class Ball{
            constructor(r,color='#000'){
                this.color=color;
                this.r=r;
                this.x=0;
                this.y=0;
            }
            draw(ctx){
                ctx.save();
                ctx.beginPath();
                ctx.fillStyle=this.color;
                ctx.arc(this.x,this.y,this.r,0,Math.PI*2);
                ctx.fill();
                ctx.restore();
            }
        }
    
        //实例化小球
        let ball=new Ball(15);
        ball.y=50;
        ball.x=width/2;
    
        //记录时间 time
        let time=new Date();
    
        //重力 gravity
        const gravity=0.01;
    
        //弹力
        const bounding=-0.8;
    
        //速度/毫秒 vy
        let vy=0.3;
        let vx=0.3;
    
        //动画方法
        function animate(){
            //时间差
            let now=new Date();
            let diff=now-time;
            time=now;
    
            //加速度
            vy+=gravity;
    
            //设置小球位置
            ball.y+=vy*diff;
            ball.x+=vx*diff;
    
            //底部碰撞
            if(ball.y+ball.r>height){
                ball.y=height-ball.r;
                vy*=bounding;
            }
            //左侧碰撞
            if(ball.x-ball.r<0){
                ball.x=ball.r;
                vx*=bounding;
            }
            //右侧碰撞
            if(ball.x+ball.r>width){
                ball.x=width-ball.r;
                vx*=bounding;
            }
    
        }
    
        //渲染方法
        !(function render(){
            //设置动画
            animate();
            //擦除
            ctx.clearRect(0,0,width,height);
            //绘图
            ball.draw(ctx);
            //递归调用render 函数
            window.requestAnimationFrame(render);
        })()
    </script>
    

    canvas-03

    补间动画

    颜色渐变

    <script src="./js/d3-color.js"></script>
    <script src="./js/Tween.js"></script>
    <script>
        const [width,height]=[window.innerWidth,window.innerHeight];
        const canvas=document.getElementById('canvas');
        canvas.width=width;
        canvas.height=height;
        const  ctx=canvas.getContext('2d');
    
        //小球对象
        class Ball{
            constructor(r,color='#000'){
                this.color=color;
                this.r=r;
                this.x=0;
                this.y=0;
            }
            draw(ctx){
                ctx.save();
                ctx.beginPath();
                ctx.fillStyle=this.color;
                ctx.arc(this.x,this.y,this.r,0,Math.PI*2);
                ctx.fill();
                ctx.restore();
            }
        }
    
        //实例化小球
        const ball=new Ball(100,'green');
        ball.x=width/2;
        ball.y=200;
    
        //实例化Tween 对象,为其添加目标对象
        let tween = new TWEEN.Tween(ball);
        //设置目标对象一段时间后的状态to({ key:val }, 时间长度)
        tween.to({color:'#00acec'}, 2000);
        //开始计时 start()
        tween.start();
        //重复 repeat(Infinity)
        tween.repeat(Infinity);
        //悠悠球 yoyo(true)
        tween.yoyo(true);
        //设置插值
        //Linear, Quadratic, Cubic, Quartic, Quintic, Sinusoidal, Exponential, Circular, Elastic, Back, Bounce
        tween.easing(TWEEN.Easing.Bounce.Out);
        //事件监听
        //onUpdate,onStart,onStop,onComplete
        tween.onUpdate(function(){
            //console.log(this.x)
        });
    
    
        //渲染方法
        !(function render(){
            //更新目标目标对象的状态
            TWEEN.update();
    
            //擦除
            ctx.clearRect(0,0,width,height);
            //绘图
            ball.draw(ctx);
            //递归调用render 函数
            window.requestAnimationFrame(render);
        })()
    
    </script>
    

    canvas-03

    图形的拖拽

    1、矩形的拖拽

    <canvas id="canvas"></canvas>
    <script>
        const canvas=document.getElementById('canvas');
        canvas.width=window.innerWidth;
        canvas.height=window.innerHeight;
        const  ctx=canvas.getContext('2d');
    
        //矩形对象
        class Rectangle{
            constructor(width=0,height=0,color='#000'){
                this.width=width;
                this.height=height;
                this.color=color;
                this.x=0;
                this.y=0;
            }
            draw(ctx){
                const {x,y,width,height,color}=this;
                ctx.save();
                ctx.fillStyle=color;
                ctx.fillRect(x,y,width,height);
                ctx.restore();
            }
        }
    
        //实例化矩形对象
        const rect = new Rectangle(200,100);
        rect.x=100;
        rect.y=100;
    
        //鼠标位减图形位
        let subPos=null;
        //图形是否被选择
        let selected=false;
    
        //点击事件
        canvas.addEventListener('mousedown',mousedownFn);
        //移动
        canvas.addEventListener('mousemove',mousemoveFn);
        //鼠标抬起
        canvas.addEventListener('mouseup',mouseupFn);
    
        function mousedownFn(event){
            //鼠标位置
            const mousePos=getMousePos(event);
            //鼠标位减图形位
            subPos={
                x:mousePos.x-rect.x,
                y:mousePos.y-rect.y
            }
            
            //判断鼠标是否在图形中
            selected=containPoint(rect,mousePos);
            
            console.log(selected);
        }
        function mousemoveFn(event){
            //鼠标位置
            const mousePos=getMousePos(event);
            /*如果鼠标选择了图形
            *   让图形跟着鼠标动
            *   按需渲染
            * */
            if(selected){
                rect.x=mousePos.x-subPos.x;
                rect.y=mousePos.y-subPos.y;
                render();
            }
    
        }
        function mouseupFn(event){
            //鼠标抬起,取消拖拽
            selected=false;
        }
        //判断点是否在图形中
        function containPoint(obj,mousePos){
            //解构图形位置和尺寸
            const {x,y,width,height}=obj;
            //解构鼠标位置
            const {x:mx,y:my}=mousePos;
    
            //计算鼠标和图形上、下、左、右边界的关系
            const l=mx>x;
            const r=mx<x+width;
            const t=my>y;
            const b=my<y+height;
    
            return l&&r&&t&&b;
        }
    
        //获取鼠标在canvas中的位置
        function getMousePos(event){
            //获取鼠标位置
            const {clientX,clientY}=event;
            //获取canvas 边界位置
            const {top,left}=canvas.getBoundingClientRect();
            //计算鼠标在canvas 中的位置
            const x=clientX-left;
            const y=clientY-top;
            return {x,y};
        }
    
        //渲染方法
        render();
        function render(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
            rect.draw(ctx);
        }
    
    </script>
    

    2、圆形的拖拽

    <canvas id="canvas"></canvas>
    <script>
        const canvas=document.getElementById('canvas');
        canvas.width=window.innerWidth;
        canvas.height=window.innerHeight;
        const  ctx=canvas.getContext('2d');
    
        //简单圆形
        class Ball{
            constructor(r=0,color='#000'){
                this.r=r;
                this.color=color;
                this.x=0;
                this.y=0;
            }
            draw(ctx){
                const {x,y,r,color}=this;
                ctx.save();
                ctx.beginPath();
                ctx.arc(x,y,r,0,Math.PI*2);
                ctx.fillStyle=color;
                ctx.fill();
                ctx.restore();
            }
        }
    
        const ball = new Ball(90);
        ball.x=200;
        ball.y=200;
        render();
    
        /*鼠标拖拽*/
        //鼠标位减图形位
        let subPos=null;
        //图形是否被选择
        let selected=false;
    
        //点击事件
        canvas.addEventListener('mousedown',mousedownFn);
        //移动
        canvas.addEventListener('mousemove',mousemoveFn);
        //鼠标抬起
        canvas.addEventListener('mouseup',mouseupFn);
    
        function mousedownFn(event){
            //鼠标位置
            const mousePos=getMousePos(event);
            //鼠标位减图形位
            subPos={
                x:mousePos.x-ball.x,
                y:mousePos.y-ball.y,
            };
            //设置选择状态
            selected=containPoint(ball);
        }
        function mousemoveFn(event){
            const mousePos=getMousePos(event);
            if(selected){
                ball.x=mousePos.x-subPos.x;
                ball.y=mousePos.y-subPos.y;
                render();
            }
        }
        function mouseupFn(){
            selected=false;
        }
        //判断点是否在图形中
        function containPoint({r}){
            const {x,y}=subPos;
            //获取鼠标到圆心的距离 len
            const len=Math.sqrt(x*x+y*y);
            //判断鼠标到圆心的距离是否小于r
            return len<r;
        }
    
        //获取鼠标在canvas中的位置
        function getMousePos(event){
            //获取鼠标位置
            const {clientX,clientY}=event;
            //获取canvas 边界位置
            const {top,left}=canvas.getBoundingClientRect();
            //计算鼠标在canvas 中的位置
            const x=clientX-left;
            const y=clientY-top;
            return {x,y};
        }
    
        function render(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
            ball.draw(ctx);
        }
    
    </script>
    

    3、扇形的拖拽

    <canvas id="canvas"></canvas>
    <script>
        const canvas=document.getElementById('canvas');
        canvas.width=window.innerWidth;
        canvas.height=window.innerHeight;
        const  ctx=canvas.getContext('2d');
    
        //扇形
        class Sector{
            constructor(r=0,startAngle=0,endAngle=Math.PI*2,color='#000'){
                this.r=r;
                this.startAngle=startAngle;
                this.endAngle=endAngle;
                this.color=color;
                this.x=0;
                this.y=0;
            }
            draw(ctx){
                const {x,y,r,startAngle,endAngle,color}=this;
                ctx.save();
                ctx.beginPath();
                ctx.moveTo(x,y);
                ctx.arc(x,y,r,startAngle,endAngle);
                ctx.closePath();
                ctx.fillStyle=color;
                ctx.fill();
                ctx.restore();
            }
        }
    
        /*扇形弧度设置则:起始弧度和结束弧度都大于0*/
        const sector = new Sector(200,0,Math.PI/3);
        sector.x=200;
        sector.y=200;
        render();
    
        /*鼠标拖拽*/
        //鼠标位减图形位
        let subPos=null;
        //图形是否被选择
        let selected=false;
    
        //点击事件
        canvas.addEventListener('mousedown',mousedownFn);
        //移动
        canvas.addEventListener('mousemove',mousemoveFn);
        //鼠标抬起
        canvas.addEventListener('mouseup',mouseupFn);
    
        function mousedownFn(event){
            //鼠标位置
            const mousePos=getMousePos(event);
            //鼠标位减图形位
            subPos={
                x:mousePos.x-sector.x,
                y:mousePos.y-sector.y,
            };
            //设置选择状态
            selected=containPoint(sector,mousePos);
        }
        function mousemoveFn(event){
            const mousePos=getMousePos(event);
            if(selected){
                sector.x=mousePos.x-subPos.x;
                sector.y=mousePos.y-subPos.y;
                render();
            }
        }
        function mouseupFn(event){
            selected=false;
        }
    
        //判断点是否在图形中
        function containPoint(obj){
            const {r,startAngle,endAngle}=obj;
            //获取鼠标到圆心的距离
            const {x,y}=subPos;
            const len=Math.sqrt(x*x+y*y);
    
            //判断鼠标到圆心的距离是否小于半径
            const b1=len<r;
    
            //获取鼠标位减图形位的方向 dir
            const dir=Math.atan2(y,x);
    
            //判断鼠标向量的方向是否在扇形的夹角之间
            const b2=dir>startAngle&&dir<endAngle;
    
    
            return b1&&b2;
        }
    
        //获取鼠标位置
        function getMousePos(event){
            //获取鼠标位置
            const {clientX,clientY}=event;
            //获取canvas 边界位置
            const {top,left}=canvas.getBoundingClientRect();
            //计算鼠标在canvas 中的位置
            const x=clientX-left;
            const y=clientY-top;
            return {x,y};
        }
    
    
        function render(){
            ctx.clearRect(0,0,canvas.width,canvas.height);
            sector.draw(ctx);
        }
    
    </script>
    

    小结:1)鼠标移动距离的获取;2)判断鼠标是否在图形中;

    合成

    1、刮刮乐

    背景图资源

    canvas-03

    canvas-03

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,user-scalable=no">
        <title>刮刮乐</title>
        <style>
            body{margin: 0;overflow: hidden}
            #canvas{
                margin: 100px;
                background-image: url("./images/ggl-back.png");
            }
        </style>
    </head>
    <body>
    <canvas id="canvas"></canvas>
    <script>
        const canvas=document.getElementById('canvas');
        const ctx=canvas.getContext('2d');
    
        /*图像尺寸,遮罩图和背景图尺寸一样*/
        const [width,height]=[395,188];
        canvas.width=385;
        canvas.height=188;
    
        /*建立图像源*/
        const img=new Image();
        img.src='./images/ggl-mask.png';
        img.onload=function(){
            /*绘制遮罩层*/
            ctx.drawImage(img,0,0);
        };
    
        /*
        * 线对象 Line
        *   ctx 上下文对象
        *   drawing 是否正在绘图
        *
        *   鼠标按下 moveTo(x,y)
        *       记录正在绘图的状态 drawing
        *       保存状态
        *       设置全局合成属性globalCompositeOperation 为destination-out
        *       线宽lineWidth为30
        *       moveTo()设置路径起点
        *   鼠标移动 lineTo(x,y)
        *       lineTo()绘制下一个点
        *       stroke()描边
        *   鼠标抬起 restore()
        *       状态还原
        *       取消正在绘图的状态
        * */
        class Line{
            constructor(ctx){
                this.ctx=ctx;
                this.drawing=false;
            }
            moveTo(x,y){
                const {ctx}=this;
                this.drawing=true;
                ctx.save();
                ctx.globalCompositeOperation='destination-out';
                ctx.lineWidth=20;
                ctx.moveTo(x,y);
            }
            lineTo(x,y){
                const {ctx}=this;
                ctx.lineTo(x,y);
                ctx.stroke();
            }
            restore(){
                this.ctx.restore();
                this.drawing=false;
            }
        }
    
    
        /*实例化线对象 Line*/
        const line=new Line(ctx);
    
    
        /*==========鼠标事件===========*/
        /*鼠标按下*/
        canvas.addEventListener('mousedown',function(event){
            //鼠标左键按下
            if(event.buttons===1) {
                //获取鼠标位置
                const {x, y} = getMousePos(event);
                //绘制起点
                line.moveTo(x,y);
            }
        });
        /*鼠标移动*/
        canvas.addEventListener('mousemove',function(event){
            //鼠标左键按下且处于绘图状态
            if(event.buttons===1&&line.drawing) {
                //获取鼠标位置
                const {x, y} = getMousePos(event);
                //绘制下一个点
                line.lineTo(x,y);
            }
        });
        /*鼠标抬起*/
        canvas.addEventListener('mouseup',function(event){
            //鼠标左键按下
            if(event.buttons===1) {
                //状态还原
                line.restore();
            }
        });
    
    
        //获取鼠标在canvas中的位置
        function getMousePos(event){
            //获取鼠标位置
            const {clientX,clientY}=event;
            //获取canvas 边界位置
            const {top,left}=canvas.getBoundingClientRect();
            //计算鼠标在canvas 中的位置
            const x=clientX-left;
            const y=clientY-top;
            return {x,y};
        }
    
    </script>
    </body>
    </html>
    

    起源地下载网 » canvas-03

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元