<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>