css - 如何让 translateZ 在 svg 组中工作?
问题描述
我创建了一个 svg 图像动画。我正在尝试使用鼠标悬停来制作一些不错的效果。我想根据鼠标位置移动 svg。到目前为止,旋转部分工作正常。但我也想<g>
在 z 轴(弹出)中移动 svg 的内部,以便它们以“不同的层”出现。应该可以translateZ()
。但我无法让它工作。
const container = document.querySelector('.container');
const image = document.querySelector('.image');
const sun = document.querySelector('.sun');
const cloudBehind = document.querySelector('.cloud-center');
const cloudLeft = document.querySelector('.cloud-left');
const cloudRight = document.querySelector('.cloud-right');
const devideAxis = 10;
container.addEventListener('mousemove', e => {
let xAxis = ~(window.innerWidth / 2 - e.pageX) / devideAxis;
let yAxis = (window.innerHeight / 2 - e.pageY) / devideAxis;
image.style.transform = `rotateY(${xAxis}deg) rotateX(${yAxis}deg)`;
});
container.addEventListener('mouseenter', e => {
image.style.transition = 'none';
//popout
cloudLeft.style.transform = 'translateZ(400px)'
})
container.addEventListener('mouseleave', e => {
image.style.transition = 'all 0.5s ease';
image.style.transform = `rotateY(0deg) rotateX(0deg)`
cloudLeft.style.transform = 'translateZ(0)'
})
body,html {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
perspective: 300px;
}
.container {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.image {
width: 50%;
transform-style: preserve-3d;
}
.cloud-left {
transition: all .5s ease-out
}
.cloud-left,
.cloud-right,
.cloud-center {
transition: transform .5s;
}
.cloud-center{
fill:url(#CLOUD-CENTER);
}
.cloud-right{
fill:url(#CLOUD-FRONT);
}
.cloud-left{
fill:url(#CLOUD-FRONT);
}
.sun{
fill:url(#SUN);
}
.shine{
fill:url(#SHINE);
}
<div class="container">
<div class="image">
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 500 250" >
<g id="wheather">
<radialGradient id="SHINE" cx="100" cy="100" r="100" gradientUnits="userSpaceOnUse">
<stop offset="0.7568" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#FFF3AB"/>
</radialGradient>
<linearGradient id="SUN" gradientUnits="userSpaceOnUse" x1="27.6083" y1="98.0519" x2="169.5758" y2="98.0519">
<stop offset="0" style="stop-color:#FFF3AB"/>
<stop offset="1" style="stop-color:#FFF2C0"/>
</linearGradient>
<linearGradient id="CLOUD-CENTER" gradientUnits="userSpaceOnUse" x1="0" y1="66.2549" x2="288.0558" y2="66.2549">
<stop offset="0" style="stop-color:#8EABBF"/>
<stop offset="1" style="stop-color:#ECF1F7"/>
</linearGradient>
<linearGradient id="CLOUD-FRONT" gradientUnits="userSpaceOnUse" x1="0" y1="62.1091" x2="294.4617" y2="62.1091">
<stop offset="5.759445e-07" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#C5D6E5"/>
</linearGradient>
<!-- SUN -->
<g transform="translate(250 0)" class="sun">
<path class="shine" d="M162.4,147.8l22,0.9l-9.8-15.5c-0.2-0.5-0.5-1-0.8-1.5v0c-3.1-4.9-1.6-11.1,3-14.2l20.3-8.1l-14.9-9.9
c-0.5-0.5-1-0.9-1.5-1.3h0c-4.9-3.3-6-9.8-2.8-14.5l15-15.3l-17.3-2.9c-0.7-0.3-1.4-0.5-2.2-0.6h0c-6-1-9.7-6.9-8.4-12.6l7.3-19.6
l-16.9,4.3c-0.7,0-1.5,0.1-2.2,0.3h0c-6.3,1.6-12.5-2.9-12.9-9.4v0c0-0.2,0-0.3,0-0.4l-1.2-19.1l-13.8,10.9
c-0.6,0.3-1.1,0.7-1.7,1.1c-5.1,4-12.6,2.4-15.6-3.3l0,0c-0.2-0.5-0.5-0.9-0.8-1.3L98.6,0l-8.4,16c-0.3,0.4-0.6,0.9-0.8,1.3v0
c-3,5.8-10.5,7.4-15.6,3.3h0c-0.5-0.4-1.1-0.8-1.7-1.1L58.3,8.6l-1.2,19.1c0,0.1,0,0.3,0,0.4v0c-0.4,6.5-6.6,11-12.9,9.4h0
c-0.8-0.2-1.5-0.3-2.2-0.3l-16.9-4.3l7.3,19.6c1.3,5.7-2.4,11.6-8.4,12.6h0c-0.8,0.1-1.5,0.3-2.2,0.6L4.3,68.5l15,15.3
c3.2,4.7,2.1,11.2-2.8,14.5c-0.6,0.4-1.1,0.8-1.5,1.3L0,109.5l20.3,8.1c4.6,3,6.1,9.3,3,14.2l0,0c-0.3,0.5-0.6,1-0.8,1.5l-9.8,15.5
l22-0.9c5.4,0.9,9.3,6,8.4,11.7v0c0,0.3-0.1,0.6-0.1,0.9l-2.8,19l19.7-9.8c5-1.3,10.3,1.3,12.2,6.1l5.7,20.4l13.8-16.7
c3.9-3.4,9.7-3.4,13.5,0l13.8,16.7l5.7-20.4c2-4.9,7.3-7.4,12.2-6.1l19.7,9.8l-2.8-19c0-0.3,0-0.6-0.1-0.9v0
C153.2,153.8,157,148.7,162.4,147.8z">
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 100 100"
to="360 100 100"
dur="80s"
repeatCount="indefinite"
/>
</path>
<circle class="sun-inside" cx="98.6" cy="98.1" r="71"/>
</g>
<!-- / SUN -->
<!-- CLOUD BEHIND -->
<g transform="translate(70 70)">
<path class="cloud-center" style="transform: " d="M261.5,79.4c-3.4,0-6.6,0.6-9.6,1.8c-1.9-5.5-6-10-11.3-12.5c0-0.2,0-0.3,0-0.5c0-27.1-21.9-49-49-49
c-0.6,0-1.2,0-1.8,0c-9-11.7-23.1-19.2-39-19.2c-18,0-33.8,9.7-42.3,24.1c-3.8-3.1-8.6-5-13.8-5c-11.1,0-20.3,8.4-21.6,19.2
c-3.7-1.1-7.7-1.7-11.7-1.7C39,36.6,21,54.6,21,76.9c0,2.8,0.3,5.6,0.9,8.3C9.6,86.1,0,96.3,0,108.8c0,13.1,10.6,23.7,23.7,23.7
h237.8c14.7,0,26.6-11.9,26.6-26.6S276.2,79.4,261.5,79.4z">
<animateMotion
path="M50,0 -50,0 50,0 z"
dur="80s"
repeatCount="indefinite"
/>
</path>
</g>
<!-- / CLOUD BEHIND -->
<!-- CLOUD LEFT -->
<g transform="translate(10 126)">
<path class="cloud-left" d="M270.4,76.2C270.4,76.2,270.4,76.2,270.4,76.2c-1.1-22-19.3-39.6-41.6-39.6c-5.1,0-9.9,0.9-14.4,2.6
C206.9,16.4,185.5,0,160.2,0c-20.6,0-38.6,10.9-48.6,27.3c-4.6-1.5-9.4-2.3-14.5-2.3c-23.4,0-42.8,16.9-46.7,39.1
c-5.1-3.3-11.2-5.2-17.7-5.2C14.6,58.9,0,73.5,0,91.6c0,18,14.6,32.7,32.7,32.7h237.8c13.3,0,24-10.8,24-24
C294.5,86.9,283.7,76.2,270.4,76.2z M194.9,102.4h-0.2c0.1,0,0.1-0.1,0.2-0.1C194.9,102.4,194.9,102.4,194.9,102.4z">
<animateMotion
path="M30,0 0,0 00,0 30,0 z"
dur="15s"
repeatCount="indefinite"
/>
</path>
</g>
<!-- / CLOUD LEFT -->
<!-- CLOUD RIGHT -->
<g transform="translate(260 140)">
<path class="cloud-right" d="M228.8,73.7c0-19.9-16.1-36-36-36c-3.5,0-6.8,0.5-10,1.4c-4.4-18.7-21.2-32.7-41.3-32.7c-10.7,0-20.5,4-28,10.6
C104.6,6.6,91.4,0,76.7,0C49.9,0,28.3,21.7,28.3,48.4c0,1.6,0.1,3.2,0.2,4.8c-0.1,0-0.2,0-0.2,0C12.7,53.2,0,65.9,0,81.5
s12.7,28.3,28.3,28.3H198v-0.4C215.4,106.8,228.8,91.8,228.8,73.7z">
<animateMotion
path="M-40,0 0,0 -100,0 -40,0 z"
dur="60s"
repeatCount="indefinite"
/>
</path>
</g>
<!-- / CLOUD RIGHT -->
</g>
</svg>
</div>
</div>
主要代码内容:
所以我有body
,哪个有perspective: 300px;
。然后我有.image
which hastransform-style: preserve-3d;
和在那个元素里面我有<g>
's with classes。
例如,我有一个.cloud-left
.
所以结构基本上是:
<body>
<div class="container">
<div class="image">
<svg>
<g id="wheather">
<g class="cloud-left">...</g>
...
</g>
</svg>
</div>
</div>
</body>
在javascript中我有这个(缩短,要查看所有代码,请参阅上面的小提琴):
const cloudLeft = document.querySelector('.cloud-left'); // get the element
container.addEventListener('mouseenter', e => {
//popout
cloudLeft.style.transform = 'translateZ(400px)'
})
container.addEventListener('mouseleave', e => {
//popback
cloudLeft.style.transform = 'translateZ(0)'
})
但这不能按我的意愿工作。
我也尝试设置哪个是其他的直接父transform-style: preserve-3d;
级,但没有区别。<g id="weather">
<g>
我没有<g>
在 z 轴上移动/弹出。我是否遗漏了 svg 中的某些内容,或者这在 svg 组中不起作用?
我有另一个可行的例子,但它不是 svg:https ://jsfiddle.net/saturday99/94o5j8ts/
解决方案
好的,正如我所怀疑的那样。它适用于 svg 而不是组/路径。如图所示,路径/组仅是 2D 的。但是 svg 可以制作 3D 并继续使用translateZ
。下面是未来寻找答案的人的答案。附言。代码可以稍微清理一下,但它可以工作。
因此,基本结构现在被分成许多 svg,而不是一个包含许多组的 svg:
<body>
<div class="container">
<div class="image">
<svg class="sun">
<g>
...
</g>
</svg>
<svg class="cloud-left">
<g>
...
</g>
</svg>
...
</div>
</div>
</body>
这是“结局”代码和解决方案:https ://jsfiddle.net/saturday99/fkrh6bzm/ 。随意分叉代码。
推荐阅读
- java - 如何使用 Selenium WebDriver 与 Ace Editor 交互
- flutter - 无法在我的文档文件夹中创建新的/构建现有的 Flutter 项目
- arduino - 存储不同的 IR 原始信号 Arduino
- verilog - Verilog 程序未终止
- ios - 需要在 APNS 中立即使通知消息过期
- javascript - 为什么在我从我的 PC 中删除暂停后我的电子应用程序不运行?
- javascript - 无法读取反应 js 中未定义的属性“getAudioTracks”
- reactjs - 在 onClick NavLink 中使用 React Router 重定向
- jenkins - 可以对机器执行 ping 和 SSH 操作,但由于“主机密钥验证失败”错误,playbook 失败
- reactjs - 无法读取杜比交互 API 客户端 SDK 中未定义的属性“具有”