mirror of
https://github.com/zen-browser/www.git
synced 2025-07-07 17:05:32 +02:00
Merge pull request #644 from j14i/j14i/video-refactoring
Re-encode video files for less gpu usage
This commit is contained in:
commit
199d83f25c
28 changed files with 49 additions and 52 deletions
BIN
public/media/compact-mode/poster.webp
Normal file
BIN
public/media/compact-mode/poster.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 48 KiB |
BIN
public/media/compact-mode/video.mp4
Normal file
BIN
public/media/compact-mode/video.mp4
Normal file
Binary file not shown.
BIN
public/media/compact-mode/video.webm
Normal file
BIN
public/media/compact-mode/video.webm
Normal file
Binary file not shown.
BIN
public/media/glance/poster.webp
Normal file
BIN
public/media/glance/poster.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 97 KiB |
BIN
public/media/glance/video.mp4
Normal file
BIN
public/media/glance/video.mp4
Normal file
Binary file not shown.
BIN
public/media/glance/video.webm
Normal file
BIN
public/media/glance/video.webm
Normal file
Binary file not shown.
BIN
public/media/hero-video/poster.webp
Normal file
BIN
public/media/hero-video/poster.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 132 KiB |
BIN
public/media/hero-video/video.mp4
Normal file
BIN
public/media/hero-video/video.mp4
Normal file
Binary file not shown.
BIN
public/media/hero-video/video.webm
Normal file
BIN
public/media/hero-video/video.webm
Normal file
Binary file not shown.
BIN
public/media/split-views/poster.webp
Normal file
BIN
public/media/split-views/poster.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
BIN
public/media/split-views/video.mp4
Normal file
BIN
public/media/split-views/video.mp4
Normal file
Binary file not shown.
BIN
public/media/split-views/video.webm
Normal file
BIN
public/media/split-views/video.webm
Normal file
Binary file not shown.
BIN
public/media/whats-new/poster.webp
Normal file
BIN
public/media/whats-new/poster.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
BIN
public/media/whats-new/video.mp4
Normal file
BIN
public/media/whats-new/video.mp4
Normal file
Binary file not shown.
BIN
public/media/whats-new/video.webm
Normal file
BIN
public/media/whats-new/video.webm
Normal file
Binary file not shown.
BIN
public/media/workspaces/poster.webp
Normal file
BIN
public/media/workspaces/poster.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
BIN
public/media/workspaces/video.mp4
Normal file
BIN
public/media/workspaces/video.mp4
Normal file
Binary file not shown.
BIN
public/media/workspaces/video.webm
Normal file
BIN
public/media/workspaces/video.webm
Normal file
Binary file not shown.
|
@ -1,14 +1,9 @@
|
|||
---
|
||||
import { motion } from 'motion/react'
|
||||
import { getTitleAnimation } from '~/animations'
|
||||
import Description from '~/components/Description.astro'
|
||||
|
||||
import CompactModeVideo from '~/assets/CompactMode.webm'
|
||||
import GlanceVideo from '~/assets/Glance.webm'
|
||||
import SplitViewsVideo from '~/assets/SplitViews.webm'
|
||||
import WorkspacesVideo from '~/assets/Workspaces.webm'
|
||||
|
||||
import { getLocale, getUI } from '~/utils/i18n'
|
||||
import Description from './Description.astro'
|
||||
|
||||
import Video from './Video.astro'
|
||||
|
||||
const locale = getLocale(Astro)
|
||||
|
@ -130,8 +125,7 @@ const descriptions = Object.values(features.featureTabs).map(tab => tab.descript
|
|||
playsinline
|
||||
preload="none"
|
||||
class="feature-video"
|
||||
src={WorkspacesVideo}
|
||||
data-active="true"
|
||||
name="workspaces"
|
||||
/>
|
||||
<Video
|
||||
autoplay
|
||||
|
@ -140,7 +134,7 @@ const descriptions = Object.values(features.featureTabs).map(tab => tab.descript
|
|||
playsinline
|
||||
preload="none"
|
||||
class="feature-video"
|
||||
src={CompactModeVideo}
|
||||
name="compact-mode"
|
||||
/>
|
||||
<Video
|
||||
autoplay
|
||||
|
@ -149,7 +143,7 @@ const descriptions = Object.values(features.featureTabs).map(tab => tab.descript
|
|||
playsinline
|
||||
preload="none"
|
||||
class="feature-video"
|
||||
src={GlanceVideo}
|
||||
name="glance"
|
||||
/>
|
||||
<Video
|
||||
autoplay
|
||||
|
@ -158,7 +152,7 @@ const descriptions = Object.values(features.featureTabs).map(tab => tab.descript
|
|||
playsinline
|
||||
preload="none"
|
||||
class="feature-video"
|
||||
src={SplitViewsVideo}
|
||||
name="split-views"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -176,30 +170,45 @@ const descriptions = Object.values(features.featureTabs).map(tab => tab.descript
|
|||
descriptionEl.textContent = descriptions[0]
|
||||
}
|
||||
|
||||
function changeToFeature({ target }: { target: HTMLElement | undefined | null }) {
|
||||
target = target?.closest('.feature, .feature-tab')
|
||||
if (!target) return
|
||||
function changeToFeature({ target }: MouseEvent | { target: HTMLElement }) {
|
||||
let targetEl: HTMLElement | null = target as HTMLElement
|
||||
|
||||
const index = Array.from(features).indexOf(target) % 4
|
||||
if (index === -1) return
|
||||
if (target instanceof HTMLElement) {
|
||||
targetEl = target.closest('.feature, .feature-tab')
|
||||
}
|
||||
|
||||
if (!targetEl) {
|
||||
return
|
||||
}
|
||||
|
||||
const index = Array.from(features).indexOf(targetEl) % 4
|
||||
|
||||
if (index === -1) {
|
||||
return
|
||||
}
|
||||
|
||||
// Update both mobile and desktop elements
|
||||
features.forEach((f, i) => {
|
||||
for (let i = 0; i < features.length; i += 1) {
|
||||
const f = features[i]
|
||||
|
||||
if (i % 4 === index) {
|
||||
f.setAttribute('data-active', 'true')
|
||||
} else {
|
||||
f.removeAttribute('data-active')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Update mobile description
|
||||
const descriptionEl = document.querySelector('.feature-description')
|
||||
|
||||
if (descriptionEl && descriptions) {
|
||||
descriptionEl.textContent = descriptions[index]
|
||||
}
|
||||
|
||||
const videos = document.querySelectorAll('.feature-video') as NodeListOf<HTMLVideoElement>
|
||||
videos.forEach((vid, i) => {
|
||||
const videos = document.querySelectorAll<HTMLVideoElement>('.feature-video')
|
||||
|
||||
for (let i = 0; i < videos.length; i += 1) {
|
||||
const vid = videos[i]
|
||||
const yOffset = (i - index) * 20
|
||||
const zOffset = i === index ? 0 : -100 - Math.abs(i - index) * 50
|
||||
const scale = i === index ? 1 : 0.95
|
||||
|
@ -220,16 +229,14 @@ const descriptions = Object.values(features.featureTabs).map(tab => tab.descript
|
|||
vid.style.zIndex = String(1 - Math.abs(i - index))
|
||||
vid.pause()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for (const feature of features) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
feature.addEventListener('click', changeToFeature as any)
|
||||
feature.addEventListener('click', changeToFeature)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
changeToFeature({ target: features[0] as any })
|
||||
changeToFeature({ target: features[0] })
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
---
|
||||
import { motion } from 'motion/react'
|
||||
import { getTitleAnimation } from '~/animations'
|
||||
import HomePageVideo from '~/assets/HomePageVideo.webm'
|
||||
import Button from '~/components/Button.astro'
|
||||
import Description from '~/components/Description.astro'
|
||||
import Title from '~/components/Title.astro'
|
||||
|
@ -86,7 +85,7 @@ const {
|
|||
{...getHeroTitleAnimation()}
|
||||
>
|
||||
<Video
|
||||
src={HomePageVideo}
|
||||
name="hero-video"
|
||||
autoplay
|
||||
loop
|
||||
muted
|
||||
|
|
|
@ -1,27 +1,19 @@
|
|||
---
|
||||
const { src, class: className, ...rest } = Astro.props
|
||||
const type = src.split('.').pop() || 'webm'
|
||||
type Props = {
|
||||
name: string
|
||||
class?: string
|
||||
} & astroHTML.JSX.VideoHTMLAttributes
|
||||
|
||||
const { name, class: className, ...rest }: Props = Astro.props
|
||||
---
|
||||
|
||||
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
|
||||
<video class:list={['w-fit', className]} data-src={src} preload="none" {...rest}>
|
||||
<source src="" type={`video/${type}`} />
|
||||
<video
|
||||
class:list={['w-fit', className]}
|
||||
preload="none"
|
||||
poster={`/media/${name}/poster.webp`}
|
||||
{...rest}
|
||||
>
|
||||
<source src={`/media/${name}/video.webm`} type="video/webm" />
|
||||
<source src={`/media/${name}/video.mp4`} type="video/mp4" />
|
||||
</video>
|
||||
|
||||
<script>
|
||||
const videos = document.querySelectorAll('video[data-src]') as NodeListOf<HTMLVideoElement>
|
||||
|
||||
const loadVideo = (video: HTMLVideoElement) => {
|
||||
const source = video.querySelector('source')
|
||||
const dataSrc = video.getAttribute('data-src')
|
||||
if (dataSrc && source) {
|
||||
source.src = dataSrc
|
||||
video.removeAttribute('data-src')
|
||||
video.load()
|
||||
}
|
||||
}
|
||||
|
||||
for (const video of videos) {
|
||||
loadVideo(video)
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -5,7 +5,6 @@ import SocialMediaStrip from '~/components/SocialMediaStrip.astro'
|
|||
import ArrowRightIcon from '~/icons/ArrowRightIcon.astro'
|
||||
import Layout from '~/layouts/Layout.astro'
|
||||
|
||||
import whatsNewVideo from '~/assets/whats-new.mp4'
|
||||
import Video from '~/components/Video.astro'
|
||||
import { releaseNotes } from '~/release-notes'
|
||||
import whatsNewText from '~/release-notes/whats-new.json'
|
||||
|
@ -71,7 +70,7 @@ if (latestVersion.version.split('.').length > 2 && whatsNewText[1] !== latestVer
|
|||
</div>
|
||||
|
||||
<Video
|
||||
src={whatsNewVideo}
|
||||
name="whats-new"
|
||||
autoplay
|
||||
loop
|
||||
muted
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue