提问人:Rodolfo Awenydd Luna Bernal 提问时间:10/27/2023 更新时间:10/31/2023 访问量:49
svg mask 在 chrome 中不起作用,但在 FF 中有效
svg mask does not work in chrome but works in FF
问:
我在这里没有想法,我制作了一个动画 svg 来使用 javascript 屏蔽图像,非常简单,但它在 chrome 和 edge 中不起作用,但在 firefox 中它工作正常,控制台没有任何错误,我阅读了文档,从技术上讲它应该可以工作。我的主要目标是移动设备,所以这必须在 chrome :( 上工作这是 html 和脚本的结构:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div class="main">
<div id="logo"><img src="imgs/realestate_logo.svg" alt="" /></div>
<div class="combo">
<svg width="100%" height="100%" viewBox="0 0 400 300">
<defs>
<mask id="mask">
<rect fill="#000000" x="0" y="0" width="400" height="300"></rect>
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
</mask>
</defs>
</svg>
<div class="container">
<img src="imgs/villa.webp" alt="Your Image">
</div>
</div>
<hr />
<div class="texto">
<p>Soy el texto</p>
</div>
</div>
<script>
window.addEventListener('load', function() {
// Logo Animation
const logoElement = document.getElementById("logo");
setTimeout(() => {
logoElement.style.opacity = "1";
logoElement.style.transform = "translateY(0)";
}, 500); // Delay for half a second before starting the logo animation
const img = document.querySelector(".container img");
const circles = document.querySelectorAll("#mask circle");
// Image dimensions and circle animation
const width = img.naturalWidth;
const height = img.naturalHeight;
const aspectRatio = (height / width) * 100;
const comboElement = document.querySelector(".combo");
comboElement.style.paddingBottom = `${aspectRatio}%`;
animateCurrentCircle(0);
// Add event listener for window resize
window.addEventListener('resize', function () {
animateCurrentCircle(0); // Reset the circle animation upon resizing
});
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function animateCurrentCircle(index) {
if (index >= circles.length) {
index = 0;
}
const svgWidth = parseFloat(getComputedStyle(document.querySelector("svg")).width);
const svgHeight = parseFloat(getComputedStyle(document.querySelector("svg")).height);
let maxi = Math.min(svgWidth, svgHeight) / 2;
const r = getRandom(maxi / 4, maxi);
const maxCx = svgWidth - r;
const minCx = r;
const maxCy = svgHeight - r;
const minCy = r;
const cx = getRandom(minCx, maxCx);
const cy = getRandom(minCy, maxCy);
const circle = circles[index];
circle.setAttribute("r", r);
circle.setAttribute("cx", cx);
circle.setAttribute("cy", cy);
setTimeout(() => {
animateCurrentCircle(index + 1);
}, 400);
}
});
</script>
</body>
</html>
这是 css:
@font-face {
font-family: 'Addington';
src: url('../fonts/AddingtonCF-Light.ttf') format('truetype');
}
body, html {
height: 100%;
margin: 0;
padding: 0;
background-color: #f4f4f4;
font-family: 'Addington', serif;
}
.main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
height: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 0px;
background-color: #fff;
gap: 10px;
}
#logo img {
width: 90%;
min-width: 300px;
max-width: 400px;
height: auto;
display: block;
margin: 0 auto;
}
#logo, .combo {
width: 100%;
position: relative;
}
.combo {
width: 90%;
max-width: 720px;
min-width: 300px;
margin: 0 auto;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: auto;
}
.container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.container img {
width: 100%;
display: block;
object-fit: cover;
/*-webkit-mask-image: url(#mask);*/
-webkit-mask-size: cover;
-webkit-mask-repeat: no-repeat; /* Added to ensure mask doesn't repeat */
/*mask-image: url(#mask);*/
mask-size: cover;
mask-repeat: no-repeat; /* Added to ensure mask doesn't repeat */
height: 100%;
-webkit-mask: url(#mask);
mask: url(#mask);
}
svg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
circle {
transition: all 5s ease;
}
.texto {
font-size: 18px;
}
#logo {
opacity: 0;
transform: translateY(-50px);
transition: opacity 1s, transform 1s;
}
任何帮助将不胜感激,谢谢!!
答:
0赞
herrstrietzel
10/31/2023
#1
Firefox 是目前唯一支持应用于 HTML 元素的引用 svg 掩码的浏览器引擎。因此,您的面具在苹果移动设备(safari/webkit)上不起作用。参见 “css-tricks: Clipping and Masking in CSS”
作为解决方法,您可以将元素替换为内联 svg 元素。<img>
<image>
<div class="container">
<svg width="100%" height="100%">
<description>Your Image</description>
<image class="masked" href="https://picsum.photos/id/237/200/300" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" />
</svg>
</div>
preserveAspectRatio="xMidYMid slice"
缩放和拟合类似于 CSS 的图像object-fit:cover
window.addEventListener("load", function() {
// Logo Animation
const logoElement = document.getElementById("logo");
setTimeout(() => {
logoElement.style.opacity = "1";
logoElement.style.transform = "translateY(0)";
}, 500); // Delay for half a second before starting the logo animation
//const img = document.querySelector(".container img");
const img = document.querySelector(".container image");
const circles = document.querySelectorAll("#mask circle");
const {
width,
height
} = img.getBBox();
// Image dimensions and circle animation
const imgParentSvg = img.closest("svg");
imgParentSvg.setAttribute("viewBox", `0 0 ${width} ${height}`);
animateCurrentCircle(0);
// Add event listener for window resize
window.addEventListener("resize", function() {
animateCurrentCircle(0); // Reset the circle animation upon resizing
});
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function animateCurrentCircle(index) {
if (index >= circles.length) {
index = 0;
}
const svgWidth = parseFloat(
getComputedStyle(document.querySelector("svg")).width
);
const svgHeight = parseFloat(
getComputedStyle(document.querySelector("svg")).height
);
let maxi = Math.min(svgWidth, svgHeight) / 2;
const r = getRandom(maxi / 4, maxi);
const maxCx = svgWidth - r;
const minCx = r;
const maxCy = svgHeight - r;
const minCy = r;
const cx = getRandom(minCx, maxCx);
const cy = getRandom(minCy, maxCy);
const circle = circles[index];
circle.setAttribute("r", r);
circle.setAttribute("cx", cx);
circle.setAttribute("cy", cy);
setTimeout(() => {
animateCurrentCircle(index + 1);
}, 400);
}
});
body,
html {
height: 100%;
margin: 0;
padding: 0;
background-color: #f4f4f4;
font-family: 'Addington', serif;
}
.main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-evenly;
height: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 0px;
background-color: #fff;
gap: 10px;
}
#logo img {
width: 90%;
min-width: 300px;
max-width: 400px;
height: auto;
display: block;
margin: 0 auto;
}
#logo,
.combo {
width: 100%;
position: relative;
}
.combo {
width: 90%;
max-width: 720px;
min-width: 300px;
margin: 0 auto;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: auto;
}
.container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.container image {
width: 100%;
display: block;
height: 100%;
-webkit-mask: url(#mask);
mask: url(#mask);
}
svg {
border: 1px solid #ccc
}
circle {
transition: all 5s ease;
}
.texto {
font-size: 18px;
}
#logo {
opacity: 0;
transform: translateY(-50px);
transition: opacity 1s, transform 1s;
}
<div class="main">
<div id="logo"><img src="https://picsum.photos/id/230/100/100" alt="" /></div>
<div class="combo">
<svg width="100%" height="100%" viewBox="0 0 400 300">
<defs>
<mask id="mask">
<rect fill="#000000" x="0" y="0" width="400" height="300"></rect>
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
<circle fill="#FFFFFF" cx="200" cy="150" r="0" />
</mask>
</defs>
</svg>
<div class="container">
<svg width="100%" height="100%">
<description>Your Image</description>
<image class="masked" href="https://picsum.photos/id/237/200/300" width="100%" height="100%" preserveAspectRatio="xMidYMid slice" />
</svg>
</div>
</div>
<hr />
<div class="texto">
<p>Soy el texto</p>
</div>
</div>
评论