├── index.css ├── index.html ├── README.md ├── cultureAnimation.css └── cultureAnimation.js /index.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: 'Roboto', sans-serif; 5 | } 6 | 7 | .filler { 8 | height: 200vh; 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | justify-content: space-between; 13 | } 14 | 15 | .filler p { 16 | font-size: 2rem; 17 | font-weight: 600; 18 | text-align: center; 19 | margin: 0; 20 | } 21 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Culture Page 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |

begin

14 |

end

15 |
16 |
17 |
18 |

begin

19 |

end

20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Asset Culture Page Animation 2 | 3 | svg animation for culture page. 4 | 5 | ## Deployment 6 | 7 | Deployed via JSDelivr using the main branch. 8 | 9 | ## Implementation 10 | 11 | All that needs to be done is add the following `HTML` to your document 12 | 13 | ```HTML 14 | 15 | 16 | 17 | 18 | ``` 19 | 20 | and to select a mounting location add the following 21 | 22 | ```HTML 23 |
24 | ``` 25 | -------------------------------------------------------------------------------- /cultureAnimation.css: -------------------------------------------------------------------------------- 1 | #animationRoot { 2 | width: 100%; 3 | height: 300px; 4 | position: relative; 5 | z-index: 1; 6 | background-color: #efebe6; 7 | overflow: hidden; 8 | } 9 | 10 | #cultureGradient { 11 | width: 100%; 12 | height: 100%; 13 | position: absolute; 14 | top: 0; 15 | left: 0; 16 | background: linear-gradient(263.63deg, #efebe6 9.94%, #154571 96.89%); 17 | z-index: 0; 18 | } 19 | 20 | #topSvg { 21 | position: absolute; 22 | top: 0; 23 | left: 0; 24 | z-index: 1; 25 | } 26 | 27 | #bottomSvg { 28 | position: absolute; 29 | top: -70px; 30 | left: 0; 31 | z-index: 1; 32 | } 33 | 34 | #svgPath { 35 | z-index: 2; 36 | position: absolute; 37 | top: -35px; 38 | left: 0; 39 | } 40 | 41 | @media screen and (max-width: 1920px) { 42 | #animationRoot { 43 | height: 210px; 44 | } 45 | 46 | #bottomSvg { 47 | top: -50px; 48 | } 49 | 50 | #svgPath { 51 | top: -25px; 52 | } 53 | } 54 | 55 | @media screen and (max-width: 1440px) { 56 | #animationRoot { 57 | height: 175px; 58 | } 59 | #bottomSvg { 60 | top: -30px; 61 | } 62 | 63 | #svgPath { 64 | top: -15px; 65 | } 66 | } 67 | 68 | @media screen and (max-width: 1024px) { 69 | #animationRoot { 70 | height: 125px; 71 | } 72 | #bottomSvg { 73 | top: -20px; 74 | } 75 | 76 | #svgPath { 77 | top: -10px; 78 | } 79 | } 80 | 81 | @media screen and (max-width: 768px) { 82 | #animationRoot { 83 | height: 100px; 84 | } 85 | #bottomSvg { 86 | top: -15px; 87 | } 88 | 89 | #svgPath { 90 | top: -7.5px; 91 | } 92 | } 93 | 94 | @media screen and (max-width: 600px) { 95 | #animationRoot { 96 | height: 70px; 97 | } 98 | #bottomSvg { 99 | top: -10px; 100 | } 101 | 102 | #svgPath { 103 | top: -5px; 104 | } 105 | } 106 | 107 | @media screen and (max-width: 425px) { 108 | #animationRoot { 109 | height: 55px; 110 | } 111 | #bottomSvg { 112 | top: -7.5px; 113 | } 114 | 115 | #svgPath { 116 | top: -3.75px; 117 | } 118 | } -------------------------------------------------------------------------------- /cultureAnimation.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', () => { 2 | // target root 3 | const animationRoot = document.getElementById('animationRoot'); 4 | 5 | // create svg and path for circle to follow 6 | // const svgForPath = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); 7 | // svgForPath.setAttribute('id', 'svgPath'); 8 | // svgForPath.setAttribute('viewBox', '0 -3 50 10'); 9 | // svgForPath.style.overflow = 'hidden'; 10 | 11 | // const svgPath = document.createElementNS('http://www.w3.org/2000/svg', 'path'); 12 | // svgPath.setAttribute('d', 'm54 1c-18-5-36 5-54 0'); 13 | // svgPath.setAttribute('fill', 'transparent'); 14 | 15 | // create and append append circle to svg element 16 | // const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); 17 | // circle.setAttribute('r', '0.75px'); 18 | // circle.setAttribute('fill', '#154571'); 19 | // circle.style.zIndex = 100; 20 | // circle.style.position = 'absolute'; 21 | // circle.style.top = '0px'; 22 | // circle.style.left = '0px'; 23 | // svgForPath.appendChild(circle); 24 | 25 | // animationRoot.appendChild(svgForPath); 26 | 27 | // create top svg, path, append path to svg and then svg to root 28 | const topSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); 29 | topSvg.setAttribute('id', 'topSvg'); 30 | topSvg.setAttribute('viewBox', '0 -3 50 10'); 31 | 32 | const topSvgPath = document.createElementNS('http://www.w3.org/2000/svg', 'path'); 33 | topSvgPath.setAttribute('d', 'm0 0c18 5 36-5 54 0l0-6-54 0z'); 34 | topSvgPath.setAttribute('fill', '#F8F6F3'); 35 | topSvg.appendChild(topSvgPath); 36 | 37 | animationRoot.appendChild(topSvg); 38 | 39 | // create bottom svg, path, append path to svg and then svg to root 40 | const bottomSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); 41 | bottomSvg.setAttribute('id', 'bottomSvg'); 42 | bottomSvg.setAttribute('viewBox', '0 0 50 10'); 43 | 44 | const bottomSvgPath = document.createElementNS('http://www.w3.org/2000/svg', 'path'); 45 | bottomSvgPath.setAttribute('d', 'm54 5c-18-5-36 5-54 0l0 6 54-0z'); 46 | bottomSvgPath.setAttribute('fill', '#F8F6F3'); 47 | bottomSvg.appendChild(bottomSvgPath); 48 | 49 | animationRoot.appendChild(bottomSvg); 50 | 51 | // create gradient div 52 | const cultureGradient = document.createElement('div'); 53 | 54 | cultureGradient.setAttribute('id', 'cultureGradient'); 55 | cultureGradient.style.transform = 'translateX(-100%)'; 56 | animationRoot.appendChild(cultureGradient); 57 | 58 | const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0); 59 | 60 | const percentageScale = (top, height) => { 61 | if (top + height > vh) return 0; 62 | if (top < 0) return 1; 63 | const maxRange = vh - height; 64 | return 1 - top / maxRange; 65 | }; 66 | 67 | window.addEventListener('scroll', () => { 68 | const animationRootRect = animationRoot.getBoundingClientRect(); 69 | const animationRootTop = animationRootRect.top; 70 | const animationRootHeight = animationRootRect.height; 71 | 72 | // animate circle along svgPath 73 | // const pathLength = svgPath.getTotalLength(); 74 | const percentage = 75 | 1 - Math.max(Math.min(percentageScale(animationRootTop, animationRootHeight), 0.915), 0.01); 76 | // const point = svgPath.getPointAtLength(pathLength * percentage); 77 | // circle.setAttribute('cx', point.x); 78 | // circle.setAttribute('cy', point.y); 79 | 80 | cultureGradient.style.transform = `translateX(${ 81 | percentageScale(animationRootTop, animationRootHeight) * 100 - 100 82 | }%)`; 83 | }); 84 | }); 85 | --------------------------------------------------------------------------------