canvas绘制时,画布上有一个镂空的圆形(即背景可见),然后随着动画的进行,这个圆形的边界逐渐扩大至充满整个屏幕

 <canvas id="myCanvas" width="800" height="600"></canvas>

在不同宽高比的屏幕上,如果canvas元素没有被强制保持与窗口同样的宽高比(例如通过CSS设置其宽度和高度百分比或者响应式布局),那么即使绘制的是一个完美的圆,但由于canvas自身的拉伸或压缩,最终呈现出来的效果可能看起来像椭圆。

为了确保无论屏幕尺寸如何都能看到一个真正的圆形,你需要确保canvas元素的宽高比始终是1:1,并且它的中心点与浏览器视窗的中心点对齐。可以使用CSS来实现这个目标:

<style>
  #myCanvas {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 100vw; 
  height:calc(100vw * (600 / 800));
  pointer-events: none;
  z-index: 1;
}
</style>

<script>
   window.onload = function () {
        var canvas = document.getElementById('myCanvas');
        var ctx = canvas.getContext('2d');
        // 加载背景图片
        var backgroundImage = new Image();
        backgroundImage.src = '/images/bg.jpg';
        backgroundImage.onload = function () {
            // 获取canvas的宽度和高度
            var startTime = 0;
            var duration = 5000; // 动画持续时间(毫秒)
            var endRadius = Math.min(window.innerWidth, window.innerHeight); // 使用窗口最小尺寸确保圆形完全可见
            console.log(endRadius)
            function drawFrame(timestamp) {
                if (!startTime) {
                    startTime = timestamp;
                }
                var progress = (timestamp - startTime) / duration;

                // 清除之前的帧
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);

                // 计算当前扩散到的半径
                var currentRadius = endRadius * progress;
                // console.log(currentRadius)
                // 绘制透明圆形
                ctx.beginPath();
                ctx.arc(canvas.width / 2, canvas.height / 2, currentRadius,0, 2 * Math.PI);

                ctx.globalCompositeOperation = 'destination-out'; // 使用复合操作使颜色变为透明
                ctx.fill();

                // 恢复默认的混合模式
                ctx.globalCompositeOperation = 'source-over';

                // 判断是否动画完成
                if (progress < 1) {
                    requestAnimationFrame(drawFrame);
                } else {
                    // 动画结束后重置混合模式(如果需要的话)
                }
            }

            // 开始动画
            requestAnimationFrame(drawFrame);
        };
    };
</script>

在这里插入图片描述

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值