在的網(wǎng)頁中應用了越來越多的3D應用,特別是基于HTML5 Canvas的動畫特效,讓用戶有一種非常震撼的視覺體驗。本文收集了8個非常炫酷的3D視覺效果的HTML5動畫,都有源代碼分享,你可以學習你感興趣的HTML5動畫,一起來看看。
1、CSS3飄帶狀3D菜單
菜單帶小圖標這次我們要來分享一款很特別的CSS3菜單,菜單的外觀是飄帶狀的,并且每一個菜單項有一個精美的小圖標,鼠標滑過菜單項時,菜單項就會向上凸起,像是飄帶飄動一樣,形成非常酷的3D視覺效果。這款CSS3飄帶狀3D菜單非常適合作一些活動頁面的菜單導航。
2、HTML5/CSS3 3D紙片折疊動畫
今天我們再來分享一款非常華麗的HTML5/CSS3 3D動畫特效,盡管它目前很少能在項目中應用,但從源碼中我們可以學到很多HTML5 3D動畫的制作知識。這是一款紙片折疊動畫特效,利用HTML5和CSS3的相關特性,我們可以將一張張紙片折疊起來,形成很酷的3D動畫效果。
3、HTML5 webkit 3D立方體圖片旋轉滑塊應用
今天再來分享一款HTML5 3D立方體動畫,這個只是一個3D效果模型,你可以用圖片替換演示中的立方體4個面,這樣就可以將這款HTML5立方體旋轉動畫改造成HTML5 3D焦點圖了,由于是基于webkit的,所以有瀏覽器限制,Google Chrome最佳。
4、HTML5顏色漸變3D文字特效
之前我們已經(jīng)分享過不少HTML5文字特效,效果都還不錯,尤其是這款HTML5擺動的文字特效類似柳枝擺動,更是有非常酷的文字動畫效果。今天我們要分享一款HTML5 3D文字特效,文字的顏色是漸變的,同時有文字陰影,更加凸顯了3D立體的效果。
5、HTML5 3D圖片陰影翻轉動畫
今天我們要分享一款很酷的HTML5 3D動畫特效,這款3D特效可以為你的圖片增加陰影的效果,而且可以讓圖片在鼠標滑過的時候出現(xiàn)3D翻轉的動畫效果。這和之前分享的HTML5 3D動畫HTML5 3D正方體旋轉動畫有著類似的效果,大家也可以看看。
6、純CSS3 3D按鈕按鈕酷似牛奶般剔透
CSS3按鈕一般都可以設計的非常漂亮,利用投影、漸變等CSS3屬性特效可以把按鈕渲染的十分動感。今天分享的這款CSS3按鈕外觀非常特別,它看上去酷似晶瑩剔透的牛奶,而且在點擊按鈕時出現(xiàn)3D效果的動畫,按鈕按下時,按鈕會輕輕的彈動一下,非常逼真。
7、CSS3 3D發(fā)光切換按鈕
剛剛我們發(fā)布過一款CSS3開關切換滑動按鈕,應該說出了有點3D立體的效果外,其他都很普通。現(xiàn)在我們要來分享一款更酷的CSS3開關切換按鈕,它不僅具有3D的效果,而且可以發(fā)光,當開關處于打開狀態(tài)時,旁邊的小燈就會亮起來,然后燈光投射到開關上,效果挺逼真的。
8、CSS3 3D彈性按鈕
今天要分享的這款CSS3按鈕和這款按鈕差不錯,也同樣擁有3D的效果,按鈕在按下時帶有彈性質感。
微信搜索“IT之家”關注搶6s大禮!下載IT之家客戶端(戳這里)也可參與評論抽樓層大獎!
家好,我是yangyang.最近在弄h5網(wǎng)頁(因為是二開,并沒有使用uniapp、mintui、mui等移動端框架),做列表的時候需要實現(xiàn)上拉加載,下拉刷新.因此也查詢總結了部分經(jīng)驗來分享給大家
下拉刷新和上拉加載這兩種交互方式通常出現(xiàn)在移動端中,其本質是PC網(wǎng)頁中的分頁類似,只是交互形式不同,開源社區(qū)有很多優(yōu)秀的解決方案:better-scroll、iscroll、pulltorefresh.js...
來源:https://vue3js.cn/interview/JavaScript/pull_up_loading_pull_down_refresh.html
上拉加載的本質是頁面觸底,或者快要觸底時的動作
判斷頁面觸底我們需要先了解一下下面幾個屬性
綜上我們得出一個觸底公式:scrollTop + clientHeight >= scrollHeight
例子:
let clientHeight = document.documentElement.clientHeight; //瀏覽器高度
let scrollHeight = document.body.scrollHeight;
let scrollTop = document.documentElement.scrollTop;
let distance = 50; //距離視窗還用50的時候,開始觸發(fā);
if ((scrollTop + clientHeight) >= (scrollHeight - distance)) {
console.log("開始加載數(shù)據(jù)");
}
下拉刷新的本質是頁面本身置于頂部時,用戶下拉時需要觸發(fā)的動作
關于下拉刷新的原生實現(xiàn),主要分成三步:
例子:
Html結構如下
<main>
<p class="refreshText"></p >
<ul id="refreshContainer">
<li>111</li>
<li>222</li>
<li>333</li>
<li>444</li>
<li>555</li>
...
</ul>
</main>
監(jiān)聽touchstart事件,記錄初始的值
var _element = document.getElementById('refreshContainer'),
_refreshText = document.querySelector('.refreshText'),
_startPos = 0, // 初始的值
_transitionHeight = 0; // 移動的距離
_element.addEventListener('touchstart', function(e) {
_startPos = e.touches[0].pageY; // 記錄初始位置
_element.style.position = 'relative';
_element.style.transition = 'transform 0s';
}, false);
監(jiān)聽touchmove移動事件,記錄滑動差值
_element.addEventListener('touchmove', function(e) {
// e.touches[0].pageY 當前位置
_transitionHeight = e.touches[0].pageY - _startPos; // 記錄差值
if (_transitionHeight > 0 && _transitionHeight < 60) {
_refreshText.innerText = '下拉刷新';
_element.style.transform = 'translateY('+_transitionHeight+'px)';
if (_transitionHeight > 55) {
_refreshText.innerText = '釋放更新';
}
}
}, false);
最后,就是監(jiān)聽touchend離開的事件
_element.addEventListener('touchend', function(e) {
_element.style.transition = 'transform 0.5s ease 1s';
_element.style.transform = 'translateY(0px)';
_refreshText.innerText = '更新中...';
// todo...
}, false);
從上面可以看到,在下拉到松手的過程中,經(jīng)歷了三個階段:
首先,小編也是使用它完成,BetterScroll 是一款重點解決移動端(已支持 PC)各種滾動場景需求的插件。它的核心是借鑒的 iscroll (opens new window)的實現(xiàn),它的 API 設計基本兼容 iscroll,在 iscroll 的基礎上又擴展了一些 feature 以及做了一些性能優(yōu)化。
BetterScroll 是使用純 JavaScript 實現(xiàn)的,這意味著它是無依賴的,同時betterScroll采用插件結構設計,為此官方也擴展了很多的應用插件,今天我們討論的兩個效果也對應著它兩個插件
https://better-scroll.github.io/docs/zh-CN/plugins/pulldown.html
https://better-scroll.github.io/docs/zh-CN/plugins/pullup.html
小編在探索的過程中發(fā)現(xiàn)了一個intersectionObserver web api, 觸發(fā)了我的知識盲區(qū),這里也簡單安利下大家,后期會單獨出一篇,還有就是,如果大家想看動畫效果的,可以到b站搜索這個api的名稱能找到許多大神的視頻動畫原理介紹
IntersectionObserver 接口(從屬于 Intersection Observer API)提供了一種異步觀察目標元素與其祖先元素或頂級文檔視口(viewport)交叉狀態(tài)的方法。其祖先元素或視口被稱為根(root)。
當一個 IntersectionObserver 對象被創(chuàng)建時,其被配置為監(jiān)聽根中一段給定比例的可見區(qū)域。一旦 IntersectionObserver 被創(chuàng)建,則無法更改其配置,所以一個給定的觀察者對象只能用來監(jiān)聽可見區(qū)域的特定變化值;然而,你可以在同一個觀察者對象中配置監(jiān)聽多個目標元素。
一個最簡單的例子:
const intersectionObserver = new IntersectionObserver((entries) => {
// 如果 intersectionRatio 為 0,則目標在視野外,
// 我們不需要做任何事情。
if (entries[0].intersectionRatio <= 0) return;
loadItems(10);
console.log("Loaded new items");
});
// 開始監(jiān)聽
intersectionObserver.observe(document.querySelector(".scrollerFooter"));
html部分
<template>
<div class="drag-wrapper" ref="dragDiv">
<div class="drag_bg"></div>
<div class="drag_text f14">{{ confirmWords }}</div>
<!-- 移動的模塊 -->
<div ref="moveDiv"
@mousedown="mousedownFn($event)"
:class="{'handler_ok_bg': confirmSuccess}"
class="handler handler_bg"></div>
</div>
</template>
css部分: 由于擔心圖片源的問題,所以寫成了base64的圖片
<style scoped>
.drag{
position: relative;
background-color: #e8e8e8;
width: 100%;
height: 40px;
line-height: 40px;
text-align: center;
}
.handler{
width: 40px;
height: 40px;
border: 1px solid #ccc;
cursor: move;
position: absolute;top: 0px;left: 0px;
}
.handler_bg{
background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg==") no-repeat center;
}
.handler_ok_bg{
background: #fff url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg==") no-repeat center;
}
.drag_bg{
background-color: #7ac23c;
height: 40px;
width: 0px;
}
.drag_text{
position: absolute;
top: 0px;
width: 100%;text-align: center;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
-o-user-select:none;
-ms-user-select:none;
}
</style>
定義參數(shù)
data() {
return {
beginClientX:0, // 距離屏幕左端距離
mouseMoveStata:false, // 觸發(fā)拖動狀態(tài) 判斷
maxwidth:'', // 拖動最大寬度,依據(jù)滑塊寬度算出來的
confirmWords:'拖動滑塊驗證', // 滑塊文字
confirmSuccess:false // 驗證成功判斷
}
}
mounted() {
// 根據(jù)滑塊寬度計算可拖動最大寬度
this.maxwidth = this.$refs.dragDiv.clientWidth - this.$refs.moveDiv.clientWidth
// 監(jiān)聽手指的觸摸事件
document.getElementsByTagName('html')[0].addEventListener('mousemove', this.mouseMoveFn)
// 監(jiān)聽手指離開事件
document.getElementsByTagName('html')[0].addEventListener('mouseup', this.moseUpFn)
}
首先判斷是否觸發(fā)拖動狀態(tài),然后計算拖動的距離和模塊距離,實時賦值
//驗證成功函數(shù)
mouseMoveFn(e){
if(this.mouseMoveStata){
let width = e.clientX - this.beginClientX
if(width > 0 && width <= this.maxwidth) {
document.getElementsByClassName('handler')[0].style.left = width + 'px'
document.getElementsByClassName('drag_bg')[0].style.width = width + 'px'
}else if(width > this.maxwidth) this.successFunction()
}
},
把拖動狀態(tài)改成false,并且把滑塊移到對應的手指落下位置上
moseUpFn(e) {
this.mouseMoveState = !1 // 修改狀態(tài)
const width = e.clientX - this.beginClientX // 計算獲取寬度
if(width < this.maxwidth) { // 當寬度小于模塊的寬度時,賦值
document.getElementsByClassName('handler')[0].style.left = 0 + 'px'
document.getElementsByClassName('drag_bg')[0].style.width = 0 + 'px'
}
}
在上面html部分的handler塊里,定義了mousedown事件(mousedownFn($event))
需要阻止文件選中等瀏覽器默認行為,并把觸發(fā)拖動狀態(tài)這個閾值打開,記錄手指移動的距離
mousedownFn:function (e) {
e.preventDefault && e.preventDefault() // 阻止文字選中等 瀏覽器默認事件
this.mouseMoveStata = true // 把觸發(fā)拖動狀態(tài)這個閾值打開
this.beginClientX = e.clientX // 記錄手指移動的距離
},
至此,功能就完成了。。
完整的JS代碼如下
<script>
export default {
data(){
return {
beginClientX:0, /*距離屏幕左端距離*/
mouseMoveStata:false, /*觸發(fā)拖動狀態(tài) 判斷*/
maxwidth:'', /*拖動最大寬度,依據(jù)滑塊寬度算出來的*/
confirmWords:'拖動滑塊驗證', /*滑塊文字*/
confirmSuccess:false /*驗證成功判斷*/
}
},
mounted(){
this.maxwidth = this.$refs.dragDiv.clientWidth - this.$refs.moveDiv.clientWidth
document.getElementsByTagName('html')[0].addEventListener('mousemove',this.mouseMoveFn)
document.getElementsByTagName('html')[0].addEventListener('mouseup',this.moseUpFn)
},
methods: {
mousedownFn:function (e) {
if(!this.confirmSuccess){
e.preventDefault && e.preventDefault() //阻止文字選中等 瀏覽器默認事件
this.mouseMoveStata = true
this.beginClientX = e.clientX
}
},
//mousedoen 事件
successFunction(){
this.confirmSuccess = true
this.confirmWords = '驗證通過'
this.$emit('onValidation', true)
if(window.addEventListener){
document.getElementsByTagName('html')[0].removeEventListener('mousemove',this.mouseMoveFn)
document.getElementsByTagName('html')[0].removeEventListener('mouseup',this.moseUpFn)
}else document.getElementsByTagName('html')[0].removeEventListener('mouseup',()=>{})
document.getElementsByClassName('drag_text')[0].style.color = '#fff'
document.getElementsByClassName('handler')[0].style.left = this.maxwidth + 'px'
document.getElementsByClassName('drag_bg')[0].style.width = this.maxwidth + 'px'
},
//驗證成功函數(shù)
mouseMoveFn(e){
if(this.mouseMoveStata){
let width = e.clientX - this.beginClientX
if(width > 0 && width <= this.maxwidth) {
document.getElementsByClassName('handler')[0].style.left = width + 'px'
document.getElementsByClassName('drag_bg')[0].style.width = width + 'px'
}else if(width > this.maxwidth) this.successFunction()
}
},
//mousemove事件
moseUpFn(e){
this.mouseMoveStata = false
var width = e.clientX - this.beginClientX
if(width<this.maxwidth){
document.getElementsByClassName('handler')[0].style.left = 0 + 'px'
document.getElementsByClassName('drag_bg')[0].style.width = 0 + 'px'
}
}
}
}
</script>
公眾號:小何成長,佛系更文,都是自己曾經(jīng)踩過的坑或者是學到的東西
有興趣的小伙伴歡迎關注我哦,我是:何小玍。 大家一起進步鴨
*請認真填寫需求信息,我們會在24小時內與您取得聯(lián)系。