实例介绍
【实例简介】
【实例截图】
【核心代码】
<!doctype html> <html> <head> <meta charset="utf-8"> <title>html5 css3文字动画特效 - 站长素材</title> <style> @import "https://fonts.googleapis.com/css?family=Baloo Chettan|Gloria Hallelujah"; html, body, .anim-wrap { width: 100%; height: 100%; margin: 0; } body { font-family: Helvetica Neueu, HelveticaNeueu, Helvetica, Arial, sans-serif; overflow: hidden; } .anim-wrap { position: absolute; overflow: hidden; display: flex; justify-content: center; align-items: center; } .anim-text { font: 4em "Baloo Chettan", Helvetica Neueu, HelveticaNeueu, Helvetica, Arial; white-space: nowrap; min-width: 1em; min-height: 1.2em; border-bottom: 1px solid transparent; caret-color: #f20dcc; } .anim-text:empty, .anim-text:focus { border-bottom-color: #f20dcc; outline: none; } .char { position: relative; margin: 0 .05em; } .char, .letter-inner { display: inline-block; } .anim[data-effect=fade] > .letter { animation: fadeIn 1.5s backwards; } @keyframes fadeIn { from { opacity: 0; transform: scale(2); } } .anim[data-effect=slide] > .letter { animation: slide 1s backwards; transform-origin: bottom left; } @keyframes slide { 0% { transform: translateX(90vw) skew(-17deg) scaleX(3); animation-timing-function: ease-in; } 80% { transform: translateX(0) skew(-17deg) scaleX(3); animation-timing-function: ease-out; } 88% { transform: translateX(0) skew(12deg) scaleX(0.8); animation-timing-function: ease-in-out; } 95% { transform: translateX(0) skew(-5deg) scaleX(1); animation-timing-function: ease-in-out; } 100% { transform: translateX(0) skew(0deg) scaleX(1); animation-timing-function: ease-in-out; } } @keyframes slideIn { from { transform: translateX(70vw); } } .anim[data-effect=roll] > .letter { animation: rollIn 1.1s cubic-bezier(0, 0, 0.6, 1) backwards; } @keyframes rollIn { from { transform: translateX(90vw) rotate(1200deg); } } .anim[data-effect=peel] > .letter { animation: peelIn 2s backwards ease-in-out; } .anim[data-effect=peel] > .letter > .letter-inner { animation: rotateY 1.3s 0.7s backwards ease-in; } @keyframes peelIn { from { transform: translate(-100vw, 0); } } @keyframes rotateY { from { transform: scale(3) rotateY(180deg); } } .anim[data-effect=swivel] > .letter:not(.space)::before { background: currentColor; content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; opacity: .2; } .anim[data-effect=swivel] { perspective: 100vmax; perspective-origin: top; } .anim[data-effect=swivel] > .letter { padding: 0 .1em; animation: swivel 5s backwards; transform-origin: top; } @keyframes swivel { 0% { transform: rotateX(-90deg); } 10% { transform: rotateX(82deg); } 20% { transform: rotateX(-74deg); } 30% { transform: rotateX(66deg); } 39% { transform: rotateX(-58deg); } 48% { transform: rotateX(50deg); } 56% { transform: rotateX(-42deg); } 63% { transform: rotateX(35deg); } 70% { transform: rotateX(-28deg); } 77% { transform: rotateX(21deg); } 83% { transform: rotateX(-15deg); } 89% { transform: rotateX(9deg); } 95% { transform: rotateX(-4deg); } 100% { transform: none; } } .anim[data-effect=hop] > .letter { animation: slideIn 2s linear backwards; } .anim[data-effect=hop] > .letter > .letter-inner { animation: hop .1s 20 alternate; } @keyframes hop { to { transform: translateY(-0.6em); } } .anim[data-effect=wave] { animation: slideIn 3s linear backwards; } .anim[data-effect=wave] > .letter { animation: hop .15s 20 alternate; } .anim[data-effect=wave2] { animation: slideIn 3s linear backwards; } .anim[data-effect=wave2] > .letter { animation: inflate .5s 6 linear alternate; } @keyframes inflate { to { transform: scale(2); } } .anim[data-effect=converge] > .letter { animation: converge 2.5s forwards; } .anim[data-effect=converge] > .letter:nth-child(1n) { transform: translate(75vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(2n) { transform: translate(100vw, 90vh); } .anim[data-effect=converge] > .letter:nth-child(3n) { transform: translate(-100vw, 96vh); } .anim[data-effect=converge] > .letter:nth-child(4n) { transform: translate(1vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(5n) { transform: translate(100vw, 24vh); } .anim[data-effect=converge] > .letter:nth-child(6n) { transform: translate(81vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(7n) { transform: translate(-22vw, -100vh); } .anim[data-effect=converge] > .letter:nth-child(8n) { transform: translate(46vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(9n) { transform: translate(-5vw, -100vh); } .anim[data-effect=converge] > .letter:nth-child(10n) { transform: translate(-45vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(11n) { transform: translate(100vw, 49vh); } .anim[data-effect=converge] > .letter:nth-child(12n) { transform: translate(100vw, 75vh); } .anim[data-effect=converge] > .letter:nth-child(13n) { transform: translate(100vw, -6vh); } .anim[data-effect=converge] > .letter:nth-child(14n) { transform: translate(93vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(15n) { transform: translate(22vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(16n) { transform: translate(100vw, -47vh); } .anim[data-effect=converge] > .letter:nth-child(17n) { transform: translate(100vw, 47vh); } .anim[data-effect=converge] > .letter:nth-child(18n) { transform: translate(100vw, -13vh); } .anim[data-effect=converge] > .letter:nth-child(19n) { transform: translate(45vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(20n) { transform: translate(100vw, -73vh); } .anim[data-effect=converge] > .letter:nth-child(21n) { transform: translate(100vw, 29vh); } .anim[data-effect=converge] > .letter:nth-child(22n) { transform: translate(-48vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(23n) { transform: translate(86vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(24n) { transform: translate(-100vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(25n) { transform: translate(-8vw, -100vh); } .anim[data-effect=converge] > .letter:nth-child(26n) { transform: translate(-100vw, 44vh); } .anim[data-effect=converge] > .letter:nth-child(27n) { transform: translate(100vw, 35vh); } .anim[data-effect=converge] > .letter:nth-child(28n) { transform: translate(41vw, -100vh); } .anim[data-effect=converge] > .letter:nth-child(29n) { transform: translate(20vw, 100vh); } .anim[data-effect=converge] > .letter:nth-child(30n) { transform: translate(23vw, -100vh); } @keyframes converge { to { transform: translate(0, 0); } } .anim[data-effect=spiral] > .letter { animation: spiral 3s ease-in both; } @keyframes spiral { from { transform: rotate(720deg) translateY(-60vmax); } } .anim[data-effect=snow] > .letter { animation: snow 5s cubic-bezier(0.68, 0.21, 0.7, 1) both; } .anim[data-effect=snow] > .letter > .letter-inner { animation: sway 1s cubic-bezier(0.46, 0.03, 0.52, 0.96) 5 alternate; } @keyframes snow { from { transform: translateY(-60vh); } } @keyframes sway { from { transform: translate(2em, 0); } to { transform: none; } } .anim[data-effect=meteorite] > .char { margin: 0 .15em; animation: 0.5s cubic-bezier(0.33, 0.08, 0.7, 0.32) forwards; } .anim[data-effect=meteorite] > .letter:nth-child(30n 1) { animation-name: meteorite; transform: translate(-6.48389vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 1) > .letter-inner { transform: translate(0.00419em, 0.00817em) rotate(4.47376deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 2) { animation-name: meteorite; transform: translate(5.18049vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 2) > .letter-inner { transform: translate(-0.07254em, 0.13755em) rotate(5.32154deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 3) { animation-name: meteorite; transform: translate(2.06164vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 3) > .letter-inner { transform: translate(0.07569em, -0.06822em) rotate(-2.04423deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 4) { animation-name: meteorite; transform: translate(11.67581vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 4) > .letter-inner { transform: translate(-0.08246em, -0.05575em) rotate(6.00681deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 5) { animation-name: meteorite; transform: translate(-5.87888vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 5) > .letter-inner { transform: translate(-0.09508em, 0.03611em) rotate(9.84507deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 6) { animation-name: meteorite; transform: translate(-12.65403vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 6) > .letter-inner { transform: translate(0.09428em, -0.11027em) rotate(-3.95578deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 7) { animation-name: meteorite; transform: translate(-11.97834vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 7) > .letter-inner { transform: translate(0.09765em, 0.12939em) rotate(0.71265deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 8) { animation-name: meteorite; transform: translate(20.20496vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 8) > .letter-inner { transform: translate(0.01126em, 0.06191em) rotate(-8.7214deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 9) { animation-name: meteorite; transform: translate(-12.55705vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 9) > .letter-inner { transform: translate(-0.03434em, 0.02092em) rotate(-7.69682deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 10) { animation-name: meteorite; transform: translate(5.38038vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 10) > .letter-inner { transform: translate(-0.08378em, 0.05044em) rotate(1.84531deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 11) { animation-name: meteorite; transform: translate(15.69186vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 11) > .letter-inner { transform: translate(0.02974em, 0.02838em) rotate(4.91783deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 12) { animation-name: meteorite; transform: translate(19.18768vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 12) > .letter-inner { transform: translate(-0.06485em, 0.04586em) rotate(-8.62222deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 13) { animation-name: meteorite; transform: translate(-17.87654vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 13) > .letter-inner { transform: translate(-0.09121em, 0.14768em) rotate(-7.50893deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 14) { animation-name: meteorite; transform: translate(11.51431vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 14) > .letter-inner { transform: translate(0.07816em, 0.05717em) rotate(3.5439deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 15) { animation-name: meteorite; transform: translate(-12.47477vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 15) > .letter-inner { transform: translate(-0.05039em, -0.00396em) rotate(9.19099deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 16) { animation-name: meteorite; transform: translate(-11.11034vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 16) > .letter-inner { transform: translate(0.00633em, 0.06642em) rotate(5.04956deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 17) { animation-name: meteorite; transform: translate(9.87686vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 17) > .letter-inner { transform: translate(-0.0775em, 0.13518em) rotate(6.98645deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 18) { animation-name: meteorite; transform: translate(-21.54326vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 18) > .letter-inner { transform: translate(0.08587em, 0.09876em) rotate(1.97567deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 19) { animation-name: meteorite; transform: translate(-2.42744vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 19) > .letter-inner { transform: translate(-0.03162em, 0.0945em) rotate(-6.59714deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 20) { animation-name: meteorite; transform: translate(2.77545vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 20) > .letter-inner { transform: translate(0.05479em, 0.06678em) rotate(-2.68341deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 21) { animation-name: meteorite; transform: translate(-3.54171vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 21) > .letter-inner { transform: translate(0.0764em, -0.04548em) rotate(3.42587deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 22) { animation-name: meteorite; transform: translate(-18.77978vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 22) > .letter-inner { transform: translate(0.02712em, -0.09712em) rotate(1.63188deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 23) { animation-name: meteorite; transform: translate(-20.94836vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 23) > .letter-inner { transform: translate(-0.07261em, 0.12161em) rotate(-3.91319deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 24) { animation-name: meteorite; transform: translate(-21.87819vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 24) > .letter-inner { transform: translate(-0.01437em, 0.0646em) rotate(-6.31852deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 25) { animation-name: meteorite; transform: translate(-20.51654vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 25) > .letter-inner { transform: translate(-0.0084em, -0.03249em) rotate(-3.0008deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 26) { animation-name: meteorite; transform: translate(-9.12595vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 26) > .letter-inner { transform: translate(-0.00576em, 0.13715em) rotate(2.74989deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 27) { animation-name: meteorite; transform: translate(-4.6315vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 27) > .letter-inner { transform: translate(-0.03443em, 0.06653em) rotate(-2.0605deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 28) { animation-name: meteorite; transform: translate(-6.03076vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 28) > .letter-inner { transform: translate(-0.02798em, -0.09215em) rotate(-6.00461deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 29) { animation-name: meteorite; transform: translate(20.93875vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 29) > .letter-inner { transform: translate(-0.07571em, 0.14403em) rotate(3.03374deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=meteorite] > .letter:nth-child(30n 30) { animation-name: meteorite; transform: translate(-10.57748vw, -60vh); } .anim[data-effect=meteorite] > .letter:nth-child(30n 30) > .letter-inner { transform: translate(0.04664em, -0.04971em) rotate(5.38089deg); } @keyframes meteorite { to { transform: none; } } .anim[data-effect=bounce] > .letter { animation: bounce 2s ease-in both; } @keyframes bounce { 0% { transform: translateY(-60vh); animation-timing-function: cubic-bezier(0.5, 0, 0.82, 0.52); } 37% { transform: none; animation-timing-function: cubic-bezier(0.18, 0.48, 0.5, 1); } 55% { transform: translateY(-25vh); animation-timing-function: cubic-bezier(0.5, 0, 0.82, 0.52); } 73% { transform: none; animation-timing-function: cubic-bezier(0.18, 0.48, 0.5, 1); } 81% { transform: translateY(-10vh); animation-timing-function: cubic-bezier(0.5, 0, 0.82, 0.52); } 89% { transform: none; animation-timing-function: cubic-bezier(0.18, 0.48, 0.5, 1); } 93% { transform: translateY(-4vh); animation-timing-function: cubic-bezier(0.5, 0, 0.82, 0.52); } 97% { transform: none; animation-timing-function: cubic-bezier(0.18, 0.48, 0.5, 1); } 98.5% { transform: translateY(-1.1vh); animation-timing-function: cubic-bezier(0.5, 0, 0.82, 0.52); } 100% { transform: none; animation-timing-function: cubic-bezier(0.18, 0.48, 0.5, 1); } } .anim[data-effect=float] > .letter { animation: float 18s ease-in-out backwards; } .anim[data-effect=float] > .letter > .letter-inner { animation: float-perpetual ease-in-out 10s 18s infinite alternate; } @keyframes float { 0% { transform: translateY(60vh); } 33% { transform: translateY(-8vh); } 51% { transform: translateY(6vh); } 66% { transform: translateY(-4vh); } 80% { transform: translateY(3vh); } 91% { transform: translateY(-1.3vh); } 100% { transform: none; } } @keyframes float-perpetual { 0% { transform: translateY(0); } 37% { transform: translateY(-1.5vh); } 58% { transform: translateY(1.3vh); } 81% { transform: translateY(-1vh); } 100% { transform: translateY(0.8vh); } } .anim[data-effect=bubble] > .letter { position: relative; animation: bubble-letter 1.3s cubic-bezier(0, 0, 0.33, 1) both; } .anim[data-effect=bubble] > .letter::after { content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border: 3px solid; border-radius: 999px; animation: bubble 2.6s cubic-bezier(0, 0.41, 0.28, 1) both; animation-delay: inherit; } .anim[data-effect=bubble] > .letter::before { content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); background: currentColor; border-radius: 999px; animation: bubble 2.6s cubic-bezier(0, 0.41, 0.28, 1) both; animation-delay: inherit; opacity: 0.3; } @keyframes bubble-letter { from { opacity: 0; } to { opacity: 1; } } @keyframes bubble { from { width: 0; height: 0; } to { width: 10em; height: 10em; opacity: 0; visibility: hidden; } } .btn, .control { padding: .5em 1em; font-size: 1.2em; } .btn { background: #f20dcc; border: 1px solid transparent; color: white; cursor: pointer; transition: .25s; } .btn:hover, .btn:focus { background: #f655db; } select { border: none; outline-color: #f20dcc; } #controls { position: absolute; right: 1px; top: 1px; border-bottom-left-radius: 5px; box-shadow: -1px 2px 13px rgba(51, 0, 43, 0.4); } #controls button { width: -moz-available; width: -webkit-fill-available; width: fill-available; border-bottom-left-radius: 5px; } .hide { display: none !important; } .alert { position: absolute; bottom: -1.6em; left: 50%; transform: translateX(-50%); padding: .4em 1em 2em; background: #f20dcc; color: #fff0fc; animation: 2s 40s peep-in both ease-in-out; border-radius: 5px; box-shadow: 0 -1px 6px 1px rgba(242, 13, 204, 0.3); } .alert.close { animation: peep-out .8s linear both; } @keyframes peep-in { 0% { transform: translate(-50%, 100%); animation-timing-function: linear; } 76% { transform: translate(-50%, -18%); } 90% { transform: translate(-50%, -20%); } 98% { transform: translate(-50%, 8%); } 100% { transform: translate(-50%, 0); } } @keyframes peep-out { to { transform: translate(-50%, 100%); visibility: hidden; } } .dismiss { border: none; background: #ff70e7; color: white; padding: .2em .5em; cursor: pointer; margin-left: .2em; } .tip { position: absolute; color: #f20dcc; animation: show-tip .5s 15s ease-in both; font-size: 1.3rem; font-family: "Gloria Hallelujah", cursive; } @keyframes show-tip { from { visibility: hidden; opacity: 0; } } .tip .text { text-shadow: -1px 2px 4px rgba(51, 0, 43, 0.2); } .tip strong { font-weight: normal; } .tip svg { width: 110px; height: auto; -webkit-filter: drop-shadow(-1px 3px 5px rgba(51, 0, 43, 0.3)); filter: drop-shadow(-1px 3px 5px rgba(51, 0, 43, 0.3)); animation: show-tip .5s 15.1s ease-in both; } .tip svg path { fill: #f20dcc; } @keyframes show-tip-arrow { 0% { visibility: hidden; opacity: 0; transform: scale(0); } 85% { visibility: visible; opacity: 1; transform: scale(1.2); } 100% { visibility: visible; opacity: 1; transform: none; } } .tip-effect { left: -120px; top: .5em; animation-delay: 20s; } .tip-effect .text { width: 110px; display: flex; justify-content: center; white-space: nowrap; margin-left: -40px; } .tip-effect svg { animation-delay: 20.1s; } .tip-type { display: flex; left: 50%; top: calc(50% - 6rem); transform: translateX(-50%); animation-delay: 12s; } .tip-type svg { animation-delay: 12.1s; width: 40px; height: 40px; margin-top: .8em; margin-left: 20px; transform: rotate(-9deg); -webkit-filter: drop-shadow(0px 1px 3px rgba(51, 0, 43, 0.3)); filter: drop-shadow(0px 1px 3px rgba(51, 0, 43, 0.3)); } </style> </head> <body> <div class="anim-wrap"> <div class="anim-text" contenteditable spellcheck="false">sc.chinaz.com</div> </div> <div id="controls"> <select name="selectEffect" id="selectEffect" class="control"> <option value="fade">Fade in</option> <option value="slide">Slide in</option> <option value="roll">Roll in</option> <option value="hop">Hop in</option> <option value="converge">Converge</option> <option value="spiral">Spiral</option> <option value="snow">Snow</option> <option value="meteorite">Meteorite</option> <option value="bounce">Bounce</option> <option value="peel">Peel</option> <option value="swivel">Swivel</option> <option value="float">Float</option> <option value="bubble">Bubble</option> </select> <div> <button class="btn animate">Animate</button> </div> <div class="tip tip-effect"> <svg width="100px" height="100px" viewBox="0 0 100 100"> <path d="M87.7,10.2c0,0-0.5,0-1.6,0c-1,0-2.5,0-4.4,0.1c-0.9,0-2,0.1-3.1,0.2c-1.1,0-2.3,0.2-3.6,0.3c-1.3,0.1-2.7,0.4-4.1,0.6 c-0.7,0.1-1.5,0.2-2.2,0.4c-0.7,0.2-1.5,0.3-2.3,0.5c-3.1,0.6-6.5,1.7-9.9,2.9c-3.4,1.3-7,2.8-10.5,4.8c-3.5,2-6.9,4.4-10.1,7.1 c-3.2,2.8-6,6-8.6,9.4l-1.9,2.6l-1.8,2.6c-0.6,0.9-1.1,1.8-1.7,2.7c-0.6,0.9-1.1,1.8-1.7,2.7c-2.2,3.6-4.1,7.3-5.9,10.8 C12.5,61.4,11,65,9.7,68.4c-0.6,1.7-1.3,3.4-1.8,5.1c-0.5,1.7-1,3.3-1.5,4.8c-0.9,3.1-1.6,6-2.2,8.6c-0.3,1.3-0.5,2.5-0.8,3.6 c-0.2,1.1-0.4,2.1-0.6,3.1c-0.4,1.9-0.5,3.3-0.7,4.3c-0.2,1-0.2,1.5-0.2,1.5l0,0c0,0.2-0.2,0.3-0.4,0.3c-0.2,0-0.3-0.2-0.3-0.4 c0,0,0.1-0.5,0.2-1.5c0.1-1,0.3-2.5,0.6-4.4c0.1-0.9,0.3-2,0.5-3.1C2.8,89.2,3,88,3.2,86.7c0.5-2.6,1.1-5.5,1.8-8.7 c0.8-3.2,1.7-6.6,2.8-10.2c1.2-3.6,2.4-7.3,4-11.1c1.6-3.8,3.5-7.6,5.7-11.3c2.3-3.7,4.9-7.3,7.8-10.5c2.9-3.3,6.1-6.3,9.4-9.1 c3.3-2.8,6.8-5.3,10.2-7.4c3.5-2.1,7.1-3.9,10.7-5.2c0.9-0.3,1.8-0.6,2.7-0.9c0.9-0.3,1.7-0.6,2.6-0.8c1.7-0.4,3.4-0.9,5-1.1 c0.8-0.1,1.6-0.3,2.4-0.4c0.8-0.1,1.5-0.2,2.3-0.3c1.5-0.2,2.9-0.3,4.2-0.4c1.3,0,2.6-0.2,3.7-0.1c1.2,0,2.2,0,3.2,0 c1.9,0,3.4,0.2,4.4,0.3c1,0.1,1.6,0.1,1.6,0.1c0.2,0,0.3,0.2,0.3,0.4C88,10.1,87.9,10.2,87.7,10.2z"> <path d="M79.9,20.8c0.5-0.7,1.1-1.4,1.7-2c0.6-0.6,1.2-1.3,1.9-1.9c0.7-0.6,1.3-1.1,2-1.7c0.4-0.3,0.7-0.5,1.1-0.8 c0.4-0.2,0.7-0.5,1.1-0.7c1.5-0.9,3-1.7,4.6-2.5l2.3-1.1c0.8-0.3,1.5-0.8,2.3-1.2l0,1.7L94,9.4c-0.9-0.5-1.9-1-2.9-1.4 c-2-0.8-4-1.5-6-2.1L79,4c-1-0.3-2-0.7-3.1-1.1c-1-0.4-2-0.9-2.9-1.5c-0.1-0.1-0.1-0.3-0.1-0.4C73,0.9,73.2,0.9,73.3,1l0,0 c0.8,0.6,1.8,1,2.8,1.3c1,0.4,2,0.6,3.1,0.9l6.2,1.6c2.1,0.5,4.2,1.1,6.2,1.8c1,0.3,2.1,0.7,3.1,1.1c1,0.4,2,0.9,3,1.4l1.6,1 l-1.7,0.7c-1.6,0.7-3.1,1.4-4.7,2.2c-1.5,0.7-3,1.5-4.5,2.3c-0.7,0.4-1.4,0.9-2.1,1.3c-0.7,0.4-1.4,0.9-2.1,1.4 c-0.7,0.5-1.4,1-2,1.5c-0.3,0.3-0.7,0.5-1,0.8l-1,0.9c-0.1,0.1-0.4,0.1-0.5,0C79.8,21.1,79.8,20.9,79.9,20.8z"> </svg> <div class="text"> <strong>Check out other effects</strong> </div> </div> </div> <div class="tip tip-type"> <div class="text"> <strong>Seriously, type something!</strong> </div> <svg width="100px" height="100px" viewBox="0 0 100 100"> <path d="M90.3,85.8c0,0,0-0.5-0.1-1.5c-0.1-1-0.1-2.5-0.2-4.3c-0.1-0.9-0.2-1.9-0.2-3c-0.1-1.1-0.3-2.3-0.4-3.6 c-0.1-0.6-0.1-1.3-0.3-2c-0.1-0.7-0.2-1.4-0.4-2.1c-0.1-0.7-0.2-1.4-0.4-2.2c-0.2-0.7-0.3-1.5-0.5-2.2c-0.7-3.1-1.7-6.3-2.9-9.7 c-1.3-3.3-2.7-6.9-4.6-10.3c-1.9-3.4-4.3-6.8-7-9.8c-2.8-3.1-6.1-5.7-9.5-8.1c-3.4-2.4-7-4.5-10.6-6.6c-3.6-2.1-7.2-3.9-10.7-5.7 c-3.5-1.8-7.1-3.3-10.4-4.7c-3.4-1.3-6.7-2.3-9.8-3.2c-3.1-0.9-5.9-1.6-8.5-2.2c-2.5-0.6-4.8-1-6.6-1.4C5.4,2.8,3.9,2.6,2.9,2.4 C2,2.3,1.4,2.2,1.4,2.2l0,0C1.1,2.1,0.9,1.8,1,1.5C1,1.2,1.3,1,1.6,1.1c0,0,0.5,0.1,1.5,0.2c1,0.1,2.5,0.2,4.3,0.5 c0.9,0.1,2,0.3,3.1,0.4c1.1,0.2,2.3,0.4,3.6,0.6c2.6,0.4,5.5,1,8.7,1.7C26,5.1,29.4,6,33,6.9C36.6,8,40.4,9,44.3,10.5 C48.1,12,52,13.7,55.7,16c3.7,2.2,7.3,4.8,10.6,7.8c0.8,0.7,1.6,1.5,2.4,2.3c0.8,0.8,1.6,1.5,2.3,2.3c1.5,1.6,3,3.2,4.4,4.8 c2.8,3.3,5.3,6.7,7.6,10.1c1.1,1.8,2.1,3.5,3,5.3c1,1.7,1.7,3.6,2.4,5.3c1.3,3.6,2.2,7,2.8,10.3c0.1,0.8,0.3,1.6,0.4,2.4 c0.1,0.8,0.2,1.5,0.3,2.3c0.2,1.5,0.3,2.9,0.3,4.2c0.1,2.7,0,5-0.1,6.9c-0.1,1.9-0.3,3.4-0.4,4.4c-0.1,1-0.2,1.5-0.2,1.5 c0,0.3-0.3,0.5-0.6,0.5C90.5,86.3,90.3,86.1,90.3,85.8z"> <path d="M78.5,77.4c0.8,0.5,1.5,1.1,2.2,1.7c0.4,0.3,0.7,0.6,1.1,1c0.3,0.3,0.7,0.7,1,1c0.6,0.7,1.3,1.4,1.8,2.2 c0.6,0.8,1.1,1.5,1.6,2.4c1,1.6,1.8,3.3,2.6,5l1.2,2.5c0.2,0.4,0.4,0.8,0.6,1.2c0.2,0.4,0.5,0.8,0.7,1.2l-3,0 c0.3-0.7,0.7-1.4,1.1-2.1c0.4-0.7,0.9-1.3,1.3-2l2.3-4.3c0.8-1.4,1.5-2.9,2.3-4.3c0.8-1.4,1.7-2.8,2.7-4.1 c0.2-0.2,0.4-0.2,0.6-0.1c0.2,0.1,0.2,0.4,0.1,0.6l0,0c-0.9,1.3-1.6,2.7-2.2,4.2c-0.6,1.5-1.2,2.9-1.8,4.4l-1.7,4.5 c-0.3,0.7-0.5,1.6-0.7,2.3c-0.2,0.8-0.6,1.5-1,2.2l-1.8,3l-1.2-3c-0.4-0.9-0.7-1.7-1.1-2.6c-0.4-0.8-0.8-1.7-1.2-2.5l-1.2-2.4 c-0.4-0.8-0.8-1.6-1.3-2.4c-0.8-1.6-1.7-3.1-2.7-4.6c-0.2-0.4-0.5-0.8-0.7-1.1c-0.3-0.4-0.5-0.7-0.8-1.1c-0.3-0.3-0.5-0.7-0.8-1.1 c-0.3-0.4-0.6-0.7-0.9-1.1c-0.2-0.3-0.1-0.6,0.1-0.8C78.1,77.2,78.3,77.2,78.5,77.4z"> </svg> </div> <div class="alert alert-come-back"> <strong>Come back again for new effects!</strong> <button class="dismiss">OK</button> </div> <script> 'use strict'; const util = { math: { degToRad: alpha => alpha * Math.PI / 180, polarToDecart: (alpha, r) => { alpha = this.degToRad(alpha); return {x: r * Math.cos(alpha), y: r * Math.sin(alpha)}; } }, color: { random: (opts = {}) => { let h, s, l; h = opts.hue || Math.floor(Math.random() * 360); s = opts.saturation || Math.floor(Math.random() * 101); l = opts.lightness || Math.floor(Math.random() * 101); return `hsl(${h}, ${s}%, ${l}%)`; } } }; /** * Make a contenteditable element more controllable */ class FunkyLetters { /** * Constructor * @param {Element} el document element with contenteditable=true or selector * @param {Object} [opts] options */ constructor(el, opts = {}) { if(typeof el == 'string') { el = document.querySelector(el); } this.container = el; this.options = opts; this._splitLetters(); this._listenToInput(); } /** * Split container's text into one letter spans optionally colored */ _splitLetters() { this.container.innerHTML = FunkyLetters.splitTextLetters(this.container.textContent, this.options); } /** * Split the text into one letter spans * @param {string} text input text * @param {Object} [opts] options * @return {string} html with text split into letters */ static splitTextLetters(text, opts = {}) { let letters; text = text.replace(/\s /, ' '); letters = text.split(/(?=.)/); return letters.reduce((a, b) => a FunkyLetters.makeLetterHtml(b, opts), ''); } /** * Generate html string for a letter * @param {string} letter single letter * @param {Object} [opts] options * @return {string} html string */ static makeLetterHtml(letter, opts = {}) { let style = '', className = 'char'; if(/\s/.test(letter)) { letter = ' '; className = ' space'; } else { className = ' letter'; } if(opts.colorize) { style = 'color:' util.color.random({saturation: 100, lightness: 50}) ';'; } return `<span class="${className}" ${style && 'style="' style '"'}><span class="letter-inner">${letter}</span></span>`; } /** * Watch input */ _listenToInput() { let me = this; // this.container.dataset.text = this.container.textContent; this.container.addEventListener('keydown', function(e) { let letterEl = me.getFocusLetter(); if(e.key.length === 1 && !e.altKey && !e.ctrlKey) { e.preventDefault(); me.insertText(e.key); return; } // If the container is empty if(!letterEl) return; switch(e.key) { // Firefox focuses in two steps on inline-block elements case 'ArrowRight': if(navigator.userAgent.indexOf('AppleWebKit') !== -1) break; if(!letterEl.nextElementSibling) break; e.preventDefault(); me.setFocus(letterEl.nextElementSibling, 1); break; case 'ArrowLeft': if(navigator.userAgent.indexOf('AppleWebKit') !== -1) break; e.preventDefault(); if(!letterEl.previousElementSibling) { me.setFocus(letterEl, 0); } else { me.setFocus(letterEl.previousElementSibling, 1); } break; case 'ArrowUp': case 'ArrowDown': e.preventDefault(); break; case 'Home': case 'PageUp': e.preventDefault(); me.setFocus(this.firstElementChild, 0); break; case 'End': case 'PageDown': e.preventDefault(); me.setFocus(this.lastElementChild, 1); break; } }); this.container.addEventListener('input', function(e) { // Firefox leaves empty containers when text is deleted. Make sure those are deleted too. me._cleanEmpty(); }); this.container.addEventListener('paste', function(e) { if(e.clipboardData.types.indexOf('text/plain') != -1) { e.preventDefault(); me.insertText(e.clipboardData.getData('text/plain')); } }); } /** * Format text and insert it into the container at the caret position * @param {string} text the text to insert */ insertText(text) { let sel = document.getSelection(), range = document.createRange(), node = this.getFocusLetter(), isBeforeNode = sel.focusOffset === 0; sel.deleteFromDocument(); if(!node) { this.container.insertAdjacentHTML('afterbegin', FunkyLetters.splitTextLetters(text, this.options)); this.setFocus(Array.from(this.container.querySelectorAll('.char')).pop(), 1); } else if(isBeforeNode) { node.insertAdjacentHTML('beforebegin', FunkyLetters.splitTextLetters(text, this.options)); this.setFocus(node.previousElementSibling, 1); } else { node.insertAdjacentHTML('afterend', FunkyLetters.splitTextLetters(text, this.options)); for(let i = text.length; i > 0 && node.nextElementSibling; i--) { node = node.nextElementSibling; } this.setFocus(node, node.textContent.length); } this.container.dataset.changed = true; this._cleanEmpty(); } /** * Get the character in focus (at caret position) * @return {Element} the element node in focus */ getFocusLetter() { const sel = document.getSelection(); return sel.anchorNode.closest ? sel.anchorNode.closest('.char') : sel.anchorNode.parentElement.closest('.char'); } /** * Set cursor position * @param {Element} node letter element to focus on * @param {Integer} offset offset. In our case, either 0 or 1 */ setFocus(node, offset) { const sel = document.getSelection(), range = document.createRange(); range.setStart(node, offset); sel.removeAllRanges(); sel.addRange(range); } /** * Delete elements other than .char the browser could have generated */ _cleanEmpty() { const focusLetter = this.getFocusLetter(); Array.from(this.container.children).forEach(el => { if(el.classList.contains('char') && el.textContent) return; if(el === focusLetter) { if(el.previousElementSibling) { this.setFocus(el, 1); } else if (el.nextElementSibling) { this.setFocus(el.nextElementSibling, 1); } } el.remove(); }); } } /** * Control animations of an element's children */ class Animator { /** * Constructor * @param {Element|string} el the container element whose children are being animated */ constructor(el) { this.container = el; this._removeClassTimer = null; // this.container.addEventListener('animationend', () => { // clearTimeout(this._removeClassTimer); // this._removeClassTimer = setTimeout(() => { // this.container.classList.remove('anim'); // }, 900); // }); } /** * Run animation using the effect * @param {string} effect effect name */ animate(effect) { const cont = this.container; if(cont.classList.contains('anim')) { cont.classList.remove('anim'); setTimeout(() => { this.animate(effect); }, 50); return; } clearTimeout(this._removeClassTimer); cont.classList.add('anim'); if(cont.dataset.effect === effect && !('changed' in cont.dataset)) return; cont.dataset.effect = effect; delete cont.dataset.changed; // if(effect !== 'converge'* && effect !== 'spiral'*/ && effect !== 'meteorite') { // Array.prototype.forEach.call(cont.children, function(el) { // el.style.transform = ''; // }); // } if(!Animator.effects[effect]) { throw new Error(`Animator: effect ${effect} is not defined`); } if(Animator.effects[effect].delays) { this.distributeDelays(Animator.effects[effect].delays); } else { this.distributeDelays({shift: false}); } } /** * Distribute animation delays * @param {Object} opts options * @param {Object} opts.shift shift each next item this much milliseconds * @param {Object} [opts.random] distribute delays randomly: without regard to document order * @param {Object} [opts.reverse] distribute delays in reverse document order starting with the last element */ distributeDelays(opts) { let shift = opts.shift != null ? opts.shift : 100, curShift = 0, els = Array.from(this.container.children); if(opts.random) { let newEls = []; for(let j = 0, l = els.length; j < l; j ) { let i = Math.floor(Math.random() * els.length); newEls.push(els.splice(i, 1)[0]); } els = newEls; } if(opts.reverse) { els = els.reverse(); } els.forEach(el => { curShift = typeof shift == 'object' ? Math.round(Math.random() * (shift.max - shift.min) shift.min) : shift; el.style.animationDelay = el.querySelector('.letter-inner').style.animationDelay = ''; if(shift === false) return; el.style.animationDelay = (parseFloat(getComputedStyle(el, null).animationDelay) curShift/1000) 's'; el.querySelector('.letter-inner').style.animationDelay = (parseFloat(getComputedStyle(el.querySelector('.letter-inner'), null).animationDelay) curShift/1000) 's'; }); } /** * Distribute children's offset positions * We are currently doing this in Sass * @param {Object} opts options */ distributeOffsets(opts) { let coords, alpha = opts.minAngle || 0, x = 100, y = 100, els = this.container.children; for(let i = 0; i < els.length; i ) { if(opts.dx || opts.dy) { x -= opts.dx || 0; y -= opts.dy || 0; } else { if(opts.random) { alpha = Math.random * (opts.maxAngle || 360 - opts.minAngle || 0) opts.minAngle || 0; coords = util.math.polarToDecart(alpha, 100); } else { coords = util.math.polarToDecart(alpha, 100); alpha = opts.dAlpha; } x = coords.x; y = coords.y; } els[i].style.transform = 'translate(' x.toFixed(3) 'vmax,' y.toFixed(3) 'vmax)'; } } } /** * The available animation effects and their settings * @type {Object} */ Animator.effects = { roll: { delays: {shift: 100} }, slide: { delays: {shift: 100} }, swivel: { delays: {shift: 100, random: true} }, peel: { delays: {shift: 70} }, wave: { delays: {shift: 30} }, wave2: { delays: {shift: 120} }, hop: { delays: {shift: 140} }, converge: { delays: {shift: false} }, fade: { delays: {shift: 80, random: true} }, snow: { delays: {shift: 600, random: true} }, spiral: { delays: {shift: 100} }, meteorite: { delays: {shift: 50, random: true} }, bounce: { delays: {shift: 200, random: true} }, float: { delays: {shift: 400, random: true} }, bubble: { delays: {shift: {min: 200, max: 500}, random: true} }, }; const animationContainer = document.querySelector('.anim-text'); let config = localStorage['funkyLetters:config']; try { config = JSON.parse(config); } catch(e) { config = { completed: {} }; } // Tips if(config.completed.changeEffect) { document.querySelector('.tip-effect').classList.add('hide'); } else { document.querySelector('#selectEffect').addEventListener('change', () => { document.querySelector('.tip-effect').classList.add('hide'); config.completed.changeEffect = true; localStorage['funkyLetters:config'] = JSON.stringify(config); }, {once: true}); } if(config.completed.type) { document.querySelector('.tip-type').classList.add('hide'); } else { animationContainer.addEventListener('keydown', () => { document.querySelector('.tip-type').classList.add('hide'); config.completed.type = true; localStorage['funkyLetters:config'] = JSON.stringify(config); }, {once: true}); } if(config.completed.comeBack) { document.querySelector('.alert-come-back').classList.add('hide'); } new FunkyLetters(animationContainer, {colorize: true}); const animator = new Animator(animationContainer); animator.animate(document.querySelector('#selectEffect').value); // Listen to controls document.querySelector('#selectEffect').addEventListener('change', function(e) { animator.animate(this.value); }); document.querySelector('.animate').addEventListener('click', function(e) { animator.animate(document.querySelector('#selectEffect').value); }); // Animate on enter key animationContainer.addEventListener('keydown', function(e) { switch(e.keyCode) { case 13: e.preventDefault(); document.querySelector('.animate').focus(); document.querySelector('.animate').click(); break; } }); // Other document.querySelector('.dismiss').addEventListener('click', function(e) { this.closest('.alert').classList.add('close'); config.completed.comeBack = true; localStorage['funkyLetters:config'] = JSON.stringify(config); }); </script> <div style="text-align:center;margin:10px 0; font:normal 14px/24px 'MicroSoft YaHei';"> <p>适用浏览器:360、FireFox、Chrome、Opera、傲游、搜狗、世界之窗. 不支持Safari、IE8及以下浏览器。</p> <p>来源:<a href="http://sc.chinaz.com/" target="_blank">站长素材</a></p> </div> </body> </html>
好例子网口号:伸出你的我的手 — 分享!
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论