feat: implement hero cloud
This commit is contained in:
parent
0298466b35
commit
d5c1b56e7f
|
@ -0,0 +1,58 @@
|
|||
.mdx-hero-asset__container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
#viewport {
|
||||
-webkit-perspective: 1000;
|
||||
-moz-perspective: 1000;
|
||||
-o-perspective: 1000;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#world {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -256px;
|
||||
margin-top: -256px;
|
||||
height: 512px;
|
||||
width: 512px;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-moz-transform-style: preserve-3d;
|
||||
-o-transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
#world div {
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-moz-transform-style: preserve-3d;
|
||||
-o-transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
.cloudBase {
|
||||
position: absolute;
|
||||
left: 256px;
|
||||
top: 256px;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
margin-left: -10px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
.cloudLayer {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
margin-left: -128px;
|
||||
margin-top: -128px;
|
||||
-webkit-transition: opacity 0.5s ease-out;
|
||||
-moz-transition: opacity 0.5s ease-out;
|
||||
-o-transition: opacity 0.5s ease-out;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,230 @@
|
|||
import React, { useEffect } from 'react'
|
||||
import './HeroAsset.scss'
|
||||
|
||||
export type HeroAssetProps = React.HTMLProps<HTMLAnchorElement> & {
|
||||
content: string
|
||||
}
|
||||
|
||||
export const HeroAsset: React.FC<HeroAssetProps> = ({ children }) => {
|
||||
useEffect(() => {
|
||||
;(function() {
|
||||
var lastTime = 0
|
||||
var vendors = ['ms', 'moz', 'webkit', 'o']
|
||||
|
||||
for (
|
||||
var x = 0;
|
||||
x < vendors.length && !window.requestAnimationFrame;
|
||||
++x
|
||||
) {
|
||||
window.requestAnimationFrame =
|
||||
window[vendors[x] + 'RequestAnimationFrame']
|
||||
//@ts-ignore
|
||||
window.cancelRequestAnimationFrame =
|
||||
window[vendors[x] + 'CancelRequestAnimationFrame']
|
||||
}
|
||||
|
||||
if (!window.requestAnimationFrame)
|
||||
//@ts-ignore
|
||||
window.requestAnimationFrame = function(callback, element) {
|
||||
var currTime = new Date().getTime()
|
||||
var timeToCall = Math.max(0, 16 - (currTime - lastTime))
|
||||
var id = window.setTimeout(function() {
|
||||
callback(currTime + timeToCall)
|
||||
}, timeToCall)
|
||||
lastTime = currTime + timeToCall
|
||||
return id
|
||||
}
|
||||
|
||||
if (!window.cancelAnimationFrame)
|
||||
window.cancelAnimationFrame = function(id) {
|
||||
clearTimeout(id)
|
||||
}
|
||||
})()
|
||||
|
||||
var layers = [],
|
||||
objects = [],
|
||||
world = document.getElementById('world'),
|
||||
viewport = document.getElementById('viewport'),
|
||||
d = 0,
|
||||
p = 400,
|
||||
worldXAngle = 0,
|
||||
worldYAngle = 0
|
||||
|
||||
//@ts-ignore
|
||||
viewport.style.webkitPerspective = p
|
||||
//@ts-ignore
|
||||
viewport.style.MozPerspective = p
|
||||
//@ts-ignore
|
||||
viewport.style.oPerspective = p
|
||||
|
||||
generate()
|
||||
|
||||
function createCloud() {
|
||||
var div = document.createElement('div')
|
||||
div.className = 'cloudBase'
|
||||
var x = 256 - Math.random() * 512
|
||||
var y = 256 - Math.random() * 512
|
||||
var z = 256 - Math.random() * 512
|
||||
var t =
|
||||
'translateX( ' +
|
||||
x +
|
||||
'px ) translateY( ' +
|
||||
y +
|
||||
'px ) translateZ( ' +
|
||||
z +
|
||||
'px )'
|
||||
div.style.webkitTransform = t
|
||||
//@ts-ignore
|
||||
div.style.MozTransform = t
|
||||
//@ts-ignore
|
||||
div.style.oTransform = t
|
||||
world.appendChild(div)
|
||||
|
||||
for (var j = 0; j < 5 + Math.round(Math.random() * 10); j++) {
|
||||
var cloud = document.createElement('img')
|
||||
//@ts-ignore
|
||||
cloud.style.opacity = 0
|
||||
var r = Math.random()
|
||||
var src = 'cloud.png'
|
||||
;(function(img) {
|
||||
img.addEventListener('load', function() {
|
||||
//@ts-ignore
|
||||
img.style.opacity = 0.8
|
||||
})
|
||||
})(cloud)
|
||||
cloud.setAttribute('src', src)
|
||||
cloud.className = 'cloudLayer'
|
||||
|
||||
var x = 256 - Math.random() * 512
|
||||
var y = 256 - Math.random() * 512
|
||||
var z = 100 - Math.random() * 200
|
||||
var a = Math.random() * 360
|
||||
var s = 0.25 + Math.random()
|
||||
x *= 0.2
|
||||
y *= 0.2
|
||||
|
||||
//@ts-ignore
|
||||
cloud.data = {
|
||||
x: x,
|
||||
y: y,
|
||||
z: z,
|
||||
a: a,
|
||||
s: s,
|
||||
speed: 0.1 * Math.random(),
|
||||
}
|
||||
|
||||
var t =
|
||||
'translateX( ' +
|
||||
x +
|
||||
'px ) translateY( ' +
|
||||
y +
|
||||
'px ) translateZ( ' +
|
||||
z +
|
||||
'px ) rotateZ( ' +
|
||||
a +
|
||||
'deg ) scale( ' +
|
||||
s +
|
||||
' )'
|
||||
cloud.style.webkitTransform = t
|
||||
//@ts-ignore
|
||||
cloud.style.MozTransform = t
|
||||
//@ts-ignore
|
||||
cloud.style.oTransform = t
|
||||
|
||||
div.appendChild(cloud)
|
||||
layers.push(cloud)
|
||||
}
|
||||
|
||||
return div
|
||||
}
|
||||
|
||||
window.addEventListener('mousewheel', onContainerMouseWheel)
|
||||
window.addEventListener('DOMMouseScroll', onContainerMouseWheel)
|
||||
window.addEventListener('mousemove', onMouseMove)
|
||||
window.addEventListener('touchmove', onMouseMove)
|
||||
|
||||
function onMouseMove(e) {
|
||||
var x = e.clientX || e.touches[0].clientX
|
||||
var y = e.clientY || e.touches[0].clientY
|
||||
|
||||
worldYAngle = -(0.5 - x / window.innerWidth) * 180
|
||||
worldXAngle = (0.5 - y / window.innerHeight) * 180
|
||||
updateView()
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
function onContainerMouseWheel(event) {
|
||||
event = event ? event : window.event
|
||||
d = d - (event.detail ? event.detail * -5 : event.wheelDelta / 8)
|
||||
updateView()
|
||||
event.preventDefault()
|
||||
}
|
||||
|
||||
function generate() {
|
||||
objects = []
|
||||
|
||||
if (world.hasChildNodes()) {
|
||||
while (world.childNodes.length >= 1) {
|
||||
world.removeChild(world.firstChild)
|
||||
}
|
||||
}
|
||||
|
||||
for (var j = 0; j < 5; j++) {
|
||||
objects.push(createCloud())
|
||||
}
|
||||
}
|
||||
|
||||
function updateView() {
|
||||
var t =
|
||||
'translateZ( ' +
|
||||
d +
|
||||
'px ) rotateX( ' +
|
||||
worldXAngle +
|
||||
'deg) rotateY( ' +
|
||||
worldYAngle +
|
||||
'deg)'
|
||||
world.style.webkitTransform = t
|
||||
//@ts-ignore
|
||||
world.style.MozTransform = t
|
||||
//@ts-ignore
|
||||
world.style.oTransform = t
|
||||
}
|
||||
|
||||
function update() {
|
||||
for (var j = 0; j < layers.length; j++) {
|
||||
var layer = layers[j]
|
||||
layer.data.a += layer.data.speed
|
||||
var t =
|
||||
'translateX( ' +
|
||||
layer.data.x +
|
||||
'px ) translateY( ' +
|
||||
layer.data.y +
|
||||
'px ) translateZ( ' +
|
||||
layer.data.z +
|
||||
'px ) rotateY( ' +
|
||||
-worldYAngle +
|
||||
'deg ) rotateX( ' +
|
||||
-worldXAngle +
|
||||
'deg ) rotateZ( ' +
|
||||
layer.data.a +
|
||||
'deg ) scale( ' +
|
||||
layer.data.s +
|
||||
')'
|
||||
layer.style.webkitTransform = t
|
||||
layer.style.MozTransform = t
|
||||
layer.style.oTransform = t
|
||||
}
|
||||
requestAnimationFrame(update)
|
||||
}
|
||||
|
||||
update()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="mdx-hero-asset__container">
|
||||
<div id="viewport">
|
||||
<div id="world"></div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export * from './HeroAsset'
|
|
@ -20,29 +20,27 @@ import {
|
|||
LogoCarousel,
|
||||
Hero,
|
||||
HeroInfo,
|
||||
HeroVideo,
|
||||
// HeroVideo,
|
||||
} from '../components/mdx'
|
||||
|
||||
import { HeroAsset } from '../components/HeroAsset'
|
||||
|
||||
<Hero size="large">
|
||||
<HeroInfo>
|
||||
<HeroTitle>
|
||||
{'LIGHT AND HIGH PERFORMING ETHEREUM CLIENTS'}
|
||||
</HeroTitle>
|
||||
<HeroDescription>
|
||||
{'Run Nimbus on lightweight devices or enterprise-grade servers with equal ease and peace of mind. Trusted by solo stakers and node operators alike.'}
|
||||
</HeroDescription>
|
||||
<HeroActions>
|
||||
<HeroAction variant="outlined" href="/about">
|
||||
Learn more
|
||||
</HeroAction>
|
||||
</HeroActions>
|
||||
</HeroInfo>
|
||||
<HeroVideo
|
||||
placeholderSrc="/hero/key-visual2.webp"
|
||||
mobile={{ height: "100%", minHeight: "80vh" }}
|
||||
/>
|
||||
</Hero>
|
||||
<Hero size="large">
|
||||
<HeroInfo>
|
||||
<HeroTitle>
|
||||
{'LIGHT AND HIGH PERFORMING ETHEREUM CLIENTS'}
|
||||
</HeroTitle>
|
||||
<HeroDescription>
|
||||
{'Run Nimbus on lightweight devices or enterprise-grade servers with equal ease and peace of mind. Trusted by solo stakers and node operators alike.'}
|
||||
</HeroDescription>
|
||||
<HeroActions>
|
||||
<HeroAction variant="outlined" href="/about">
|
||||
Learn more
|
||||
</HeroAction>
|
||||
</HeroActions>
|
||||
</HeroInfo>
|
||||
<HeroAsset />
|
||||
</Hero>
|
||||
|
||||
<FeatureList
|
||||
id="clients"
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 57 KiB |
Loading…
Reference in New Issue