信ID:WEB_wysj(點擊關注) ◎ ◎ ◎ ◎ ◎◎◎◎◎一┳═┻︻▄
(頁底留言開放,歡迎來吐槽)
● ● ●
難題:直接設置一個半透明的邊框不起作用。
解決方案:padding-box盒模型border:10px solid rgba(255,255,255,.5);background: white;background-clip: padding-box;
背景知識:box-shadow 的基本用法
box-shadow: X軸偏移量 Y軸偏移量 [模糊半徑] [擴展半徑] [陰影顏色] [投影方式];
解決方案一:
利用box-shadow的屬性擴張半徑background:
yellowgreen;box-shadow: 0 0 0 10px #655, 0 0 0 15px deeppink, 0 2px 5px 15px rgba(0,0,0,.6);
特點:box-shadow 方案只能模擬實線邊框,會貼合元素的圓角
解決方案二:outline 方案background: yellowgreen;border: 10px solid #655;outline: 5px solid deeppink;特點:實現的“邊框”不會貼合元素的圓角,可以實現虛線邊框
示例:實現一個背景圖在div右下角,距離右邊10px 下邊10px 如圖;
解決方案一:background-position擴展方案background: #58a url(code-pirate.svg) no-repeat bottom right;background-position: right 10px bottom 10px;
解決方案二:background-origin 方案padding: 10px;background: url("code-pirate.svg") no-repeat #58a bottom right; /* 或 100% 100% */background-origin: content-box;
解決方案三:calc 方案background: url("code-pirate.svg") no-repeat;background-position: calc(100% - 20px) calc(100% - 10px);
兩個div很容易實現,那么一個div呢?
解決方案:利用box-shadow和outlinebackground: tan;border-radius: .8em;padding: 1em;outline: .6em solid #655;box-shadow: 0 0 0 .4em #655;
box-shadow的寬要小于outline寬度值,大于 (Math.sqrt(2)-1)r(這里的 r 表示 border-radius)
背景知識:CSS 線性漸變,background-size
案例一:等寬的雙色水平條紋
background: linear-gradient(#fb3 50%, #58a 0);background-size: 100% 30px;
案例二:不等寬的雙色水平條紋
background: linear-gradient(#fb3 30%, #58a 0);background-size: 100% 30px;
案例三:三色水平條紋
background: linear-gradient(#fb3 33.3%, #58a 0, #58a 66.6%, yellowgreen 0);background-size: 100% 45px;
案例四:垂直條紋
background: linear-gradient(to right, /* 或 90deg */ #fb3 50%, #58a 0);background-size: 30px 100%;
案例五:斜向條紋
失敗方案:改變 background-size 的值和漸變的方向background: linear-gradient(45deg, #fb3 50%, #58a 0);background-size: 30px 30px;
正確方案:做到無縫拼接(60度的條紋不好做)background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);background-size: 30px 30px;
優化方案:重復漸變做60度條紋background: repeating-linear-gradient(60deg, #fb3, #fb3 15px, #58a 0, #58a 30px);height:100%;
案例六:靈活的同色系斜向條紋
在大多數情況下,我們想要的條紋圖案并不是由差異極大的幾種顏色組成的,這些顏色往往屬于同一色系。
失敗方案:沒有任何瀏覽器支持下面這個特性background: repeating-linear-gradient(60deg, #fb3 0 15px, #58a 0 30px);正確方案:不再為每種條紋單獨指定顏色,而是把最深的顏色指定為背景色,同時把半透明白色的條紋疊加在背景色之上來得到淺色條紋background: #58a;background-image: repeating-linear-gradient(30deg, hsla(0,0%,100%,.1), hsla(0,0%,100%,.1) 15px, transparent 0, transparent 30px);
背景知識:CSS 漸變,“條紋背景”
CSS3 圖案庫lea.verou.me/css3patterns
背景知識:CSS 漸變,“條紋背景”,“復雜的背景圖案”
大自然不會以“無縫”貼片的方式重復自己......
蟬原則:通過質數來增加隨機真實性
蟬漸變圖案:條紋圖案把不同尺寸的漸變圖案疊加起來,并使用質數來增加隨機的真實感
background: hsl(20, 40%, 90%);background-image: linear-gradient(90deg, #fb3 11px, transparent 0), linear-gradient(90deg, #ab4 23px, transparent 0), linear-gradient(90deg, #655 41px, transparent 0);background-size: 41px 100%, 61px 100%, 83px 100%;
背景知識:CSS 漸變,基本的 border-image,“條紋背景”,基本的 CSS 動畫案例一:一個元素有一圈裝飾性的邊框,基本上就是一張圖片被裁剪進了邊框所在的方環區域。不僅如此,我們還希望這個元素的尺寸在擴大或縮小時,這幅圖片都可以自動延伸并覆蓋完整的邊框區域。
最簡單的辦法是使用兩個HTML 元素:一個元素用來把我們的石雕圖片設為背景,另一個元素用來存放內容,并設置純白背景,然后覆蓋在前者之上。問題來了:如果只用一個元素,我們能做到這個效果嗎?
解決方案:padding: 1em;border: 1em solid transparent;background:linear-gradient(white, white) padding-box,url(stone-art.jpg) border-box 0 / cover;
案例二;老式信封樣式的邊框
案例三:螞蟻行軍邊框
@keyframes ants { to { background-position: 100% } }.marching-ants {padding: 1em;border: 1px solid transparent;background:linear-gradient(white, white) padding-box,repeating-linear-gradient(-45deg, black 0, black 25%, white 0, white 50%) 0 / .6em .6em;animation: ants 12s linear infinite;}
案例四:邊框的裁切效果,用來模擬傳統的腳注
border-top: .2em solid transparent;border-image: 100% 0 0 linear-gradient(90deg, currentColor 4em, transparent 0);padding-top: 1em;
干貨!免費領取騰訊高級講師網頁設計教程
點我領取
???
關注網頁設計自學平臺,99%的努力都在這里
▼無法識別二維碼可以點「閱讀原文」噢!
年前,粒子動畫席卷了網絡,并成功地為自己開辟了一個利基市場。當前對具有高科技氛圍和幾何裝飾的設計的巨大癡迷使它們成為當今更受歡迎的解決方案之一。
使用粒子動畫給人留下深刻印象
隨著時間的推移,技術成熟了。從散落在畫布上的雜亂無章的小白點,它變成了一種潛力巨大的工具。這不是什么特別的東西,但它有一定的令人驚嘆的因素。此外,它完美地為高科技、幾何和商務美學做出了貢獻——自然而然地完成了它們。
前提是:粒子動畫要給人留下深刻印象。而且,開發人員始終堅持這一假設,充分利用它。讓我們考慮一下這個解決方案的真正粉絲創建的一些驚人的代碼片段。
NO.1 Justin Windle 的 30,000 個粒子
這里的標題不言自明。船上有 30,000 個粒子,您會期待一些宏偉的東西。賈斯汀溫德爾當然達到了我們的期望。他的概念令人難以置信。用你的鼠標到處玩。物理學只是例外。這個版本的粒子動畫在開發者中很受歡迎,盡管規模沒有那么大。
NO.2 Alex Safayan 在水中的魚
Alex Safayan 提出了幾乎相同的解決方案,但在這種情況下,粒子越來越大。鼠標光標也將這些點推開,形成帶有微妙漣漪效果的痕跡。動畫的行為讓人想起魚靠近水面時的運動。注意物理學:點之間的相互作用是經過深思熟慮的。
獲得 2017 年度最受關注項目獎的 Plankton 無疑是值得關注的。該項目不僅著迷于想法,還著迷于實現。從像手套一樣適合這里的微妙色彩到看起來令人難以置信的自然的華麗行為,Marco Dell'Anna 對細節有著敏銳的洞察力。
我喜歡這里華麗的復古氛圍、霓虹燈和華麗的色彩。很難把你的眼睛從它身上移開。Stardust 是設計和編碼的共生體,是一部鼓舞人心的杰作。
Akimitsu Hamamuro 邀請您在他的游樂場添加所謂的“重力點”。它們侵入點的混亂運動,像磁鐵一樣拉動它們。雖然它們不扮演軌道中心的角色;然而,它們形成了迫使粒子向其方向移動的焦點。
如今,球體是英雄區域非常流行的風格選擇。Nate Willey 對這一趨勢的看法令人印象深刻。由于微小的顆粒,球體看起來很脆弱,同時由于經過深思熟慮的行為而堅固。他分解和重新形成球體的程序非常棒。
Kevin Rajarm 汲取了粒子動畫的美麗和優雅,并用Three.js的強大來增強它,帶來了一個精致但真正復雜的概念。令人驚嘆的海浪景色讓人感覺未來主義、人工和迷人。
還有更令人印象深刻的使用粒子動畫的方法。讓我們走出常規,開箱即用地思考:這種方法很容易使標識和字母等元素受益。
Interactive Particle Logo 就是一個典型的例子。它看起來像是上面提到的 Justin Windle 片段的重新設想的解決方案。雖然沒有 30,000 個點,但它由數量驚人的粒子組成,巧妙地組成了“CODEPEN”這個詞。這是該概念找到實際用途的案例之一。
Louis Hoebregts 在這支筆中提供了先前解決方案的彩色版本。這里的文本是由一千個彩色實心圓圈組成的,這些圓圈通過與上一個示例相同的交互性來豐富。
雖然這不是一個戲劇性的入口,但它有一些令人著迷的東西。流暢的動畫慢慢揭開人物的面紗,點燃我們的興趣。這個概念有某種神秘的風格,類似于“陌生人”的介紹。
這是Marco Dell'Anna的又一杰作。這一次,粒子動畫參與塑造了著名的耐克標志。從晦澀、半透明到明快、立體,動畫逐漸暴露了標志,不顯眼地抓住了整體的注意力。
粒子動畫是越小越好的情況之一。點越小,可以實現的效果就越令人印象深刻。一方面,由于涉及幾何和物理,它看起來很復雜。另一方面,由于精致的形狀,它看起來脆弱而微妙。這種獨特的融合使粒子動畫與眾不同且引人注目。
粒子動畫在企業網站建設中的運用案例
圖片來源:素馬設計
文:https://zhuanlan.zhihu.com/p/30487077
本文不會大篇幅介紹裝飾器(Decorator)的概念和基礎用法,核心介紹我們團隊如何將裝飾器應用于實際開發,和一些高級用法的實現。
Decorator 是 ES7 的一個新語法,正如其“裝飾器”的叫法所表達的,他可以對一些對象進行裝飾包裝然后返回一個被包裝過的對象,可以裝飾的對象包括:類,屬性,方法等。Decorator 的寫法與 Java 里的注解(Annotation)非常類似,但是一定不要把 JS 中的裝飾器叫做是“注解”,因為這兩者的原理和實現的功能還是有所區別的,在 Java 中,注解主要是對某個對象進行標注,然后在運行時或者編譯時,可以通過例如反射這樣的機制拿到被標注的對象,對其進行一些邏輯包裝。而 Decorator 的原理和作用則更為簡單,就是包裝對象,然后返回一個新的對象描述(descriptor),其作用也非常單一簡單,基本上就是獲取包裝對象的宿主、鍵值幾個有限的信息。
簡單來說,JS 的裝飾器可以用來“裝飾”三種類型的對象:類的屬性/方法、訪問器、類本身,簡單看幾個例子吧。
注意這里的 target 對應的是被裝飾的屬性所屬類的原型,如果是裝飾一個 A 類的屬性,并且 A 類是繼承自 B 類的,這時候你打印 target,獲取到的是 A.prototype,它的結構是這樣的,這里一定要注意:
[image:A944761A-E0FA-4C04-BD90-BE179C46B641-35651-00001223828250C5/187FCC2A-8CC4-46C4-B8A3-A7FD5E0376F6.png]
如果需要操作 target,可能需要搞清楚這個問題。
推薦下我的前端群:524262608,不定期會有干貨分享,初學者還有一套整理好的入門教程,歡迎初學者和進階中的小伙伴。
與屬性方法類似,就不詳述了。
其中的 target 就是類本身(而不是其 prototype)
今天,我們要介紹的主要是,如何將 Decorator 這個特性應用于數據定義層,實現一些類似于類型檢查、字段映射等功能。
關于數據定義層(Model),其實就是應用內出現的各種實體數據的定義,也就是 MVVM 中的 M 層,注意,和 VM 層做好區分,Model 本身不提供數據的管理和流通,只負責定義某個實體本身的屬性和方法,例如頁面里有一輛車的模塊,我們就定義一個 CarModel,它用來描述車輛的顏色、價格、品牌等信息。
關于為什么要在前端應用內定義明確的 Model,這個我之前在知乎上也早有論述,核心幾點:
提高可維護性。將數據源頭的實體做一個固定而準確的描述,這個對于串聯理解整個應用非常重要,特別是在重構或者接手別人的代碼的時候,你需要準確的知道一個頁面(或者是一個模塊)它會包含哪些數據,這些數據分別有哪些字段,這樣更便于理解整個應用的數據邏輯。
提高確定性。當你要給你的界面增加幾個車輛字段的時候,你不清楚之前是否已經定義過這些字段,服務端是否會返回這些字段,可能要請求一下(并且要有權限取到所有字段)才能知道,但是如果有 model 的明確定義,有什么字段就一目了然了。
提高開發效率。在這一層統一做一些數據映射和類型檢查等工作,這也是今天要講的重點。
以我們團隊 RN 開發框架中 Model 部分的實現為例,我們至少提供了三個基礎的基于 Decorator 的功能:類型檢查,單位轉換,字段映射。接下來我會先簡單介紹下這幾個功能是做什么的,隨后介紹如何實現這些 Decorator。
先來看看最終調用時候的代碼
可以看到我們有三個自定義的 decorator :
@Unit, // 單位轉換裝飾器 @Check, // 類型檢查裝飾器, @ServerName // 數據字段映射裝飾器,當前后端定義的字段名不一致的時候用
@Unit 是一個比較特殊的裝飾器,它的作用是在前后端之間自動轉換單位,也就是前端和后端交換某些帶單位的數據的時候,會把根據各端的注解和裝飾器,把真實值轉換成帶單位的值傳給另一端,然后另一端會在框架層自動轉成它定義的單位,以此解決前后端單位不一致,交換數據時混亂導致的問題。
被 @Unit 裝飾過的屬性,讀寫的時候都是按照前端的單位讀寫,然后再轉換成 JSON 的時候就會特殊處理成類似 12.3_$wy 這樣的格式,表示這個數的單位是萬元。
@Check 更為容易理解,就是用來檢查字段類型,或者檢查字段格式,或者一些自定義檢查,例如正則表達式等。
@ServerName 則用來做映射,例如前后端對同一個界面元素的命名不同,這時候不需要完全按照服務端的命名來決定,可以在前端用另外一個屬性名,然后將其裝飾成服務端的字段名。
我們的目標就是實現這幾個 Decorator,按照之前對 Decorator 的科普,其實要獨立實現這幾個功能其實非常簡單。
以 @Check 為例,我們改寫被包裝屬性的 descriptor,返回一個新的 descriptor,將被包裝屬性的 getter 和 setter 重新定義,然后在其調用 setter 的時候先檢查傳入參數的類型和格式,做一些對應的處理。
非常簡單,其他幾個 Decorator 的實現也類似,可能像@Unit 這種實現起來會稍顯復雜,不過只要在 Decorator 中記住每個屬性標注的單位,在序列化的時候獲取對應的屬性對應的單位然后做轉換就可以了。
但是,到這里,問題其實還沒有完!
我們的確實現了一個可用的 Decorator,但是這些 Decorator 可以疊加使用嗎?另外可以和業界常用的一些 Decorator 混用嗎?例如 mobx 中的 @ observable。也就是我上面最開始的實例的用法:
@observable@Check(CheckType.String)@ServerName('seller_name')sellerName = '';
如果你按照我剛才的方式實現 @Check 和 @ServerName 的話,你會發現兩個致命的問題:
這兩個自己實現的 Decorator 首先就沒法疊加使用。
這兩個 Decorator 都無法和 @observable 這個同時使用。
為什么呢?問題就出在我們改寫屬性的 getter 和 setter 的實現原理上。首先,每次給一個屬性定義 getter 和 setter 都會覆蓋前一次的定義,也就是這個動作只能有一次。然后,mobx 的實現非常依賴對 getter 和 setter 的定義
事實上,Decorator 本身疊加使用時沒問題的,因為你的每次包裝,都會將屬性的 descriptor 返回給上一層的包裝,最后就是一個函數包函數包函數的效果,最終返回的還是這個屬性的 descriptor 。
那我們就需要摒棄掉定義 getter 和 setter 的實現方式。其實除了這種方式,還有很多方式可以實現上述的功能,核心就是一點,在裝飾器函數里,將你需要處理的屬性和對這個屬性需要做的處理的對應關系都記錄下來,然后在處理實例化數據和序列化數據的時候,把對應關系取出來,執行相關邏輯即可。
廢話不說,我們直接上一種將這個對應關系掛載到類的原型上的一個實現方式。
注意,我前面提到的一個信息,裝飾函數的第一個參數 target 是包裝屬性所屬的類的原型(prototype),這個通過看 babel 編譯后的結果可以看到。然后我這里為什么將對應關系掛載到 target.constructor 上,是因為我所有的 Model 類,都是繼承自我提供的一個 Model 基類的(BaseModel),target 拿到的不是子類的原型,而是基類的原型,target.constructor 拿到的才是最終的子類。也就是我把對應關系掛載到了開發定義的子類上。
接下來看看基類的代碼,核心提供兩個方法,分別是映射數據和序列化的方法。
在 __map 函數中,我們將當前類(this.constructor)上的對應關系都取出來,然后做數據校驗和映射,這里應該不難理解了。
最終應用的代碼就是我們開篇貼出來最終使用的代碼,只要相應的 Model 類繼承自 BaseModel 即可。
推薦下我的前端群:524262608,不定期會有干貨分享,初學者還有一套整理好的入門教程,歡迎初學者和進階中的小伙伴。
通過這樣的方式實現的 Decorator ,因為沒有用到任何 getter setter 相關的功能,所以可以和 mobx 這樣的庫完美融合,并且可以無限疊加使用,不過如果你用到了多個三方庫,他們都提供了對應的 Decorator,然后又都修改了 getter 和 setter,那就沒有辦法了!
Decorator 雖然原理非常簡單,但是的確可以實現很多實用又方便的功能,目測前端領域很多框架和庫都會大規模使用這個特性,但是也希望這些庫在實現 Decorator 的時候考慮下通用性,考慮下疊加和共存的問題。像上面 mobx 的 @observable,不關無法疊加,而且和我自己實現的 Decorator 的順序都不能亂,必須在最外層,因為它改變了整個屬性的性質,不寫在最外層的時候,會發現一些莫名其妙的問題。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。