隨著車內屏幕越來越多,越來越大,駕駛者在開車過程中因操作屏幕而分心機率逐漸升高。眾多汽車制造商均希望探索出一種降低或避免「駕駛員分心」的安全性技術。
手勢,是指人手、手和手臂結合產生的動作,作為解決「駕駛者分神」這個痛點的解決方案之一,正在全世界的汽車制造商中掀起「熱浪」。
你只需要隨意的揮一揮手,就能掛斷電話;將手指向順時針或者逆時針方向移動,就能調整音量大小。
汽車手勢的出現,源于對車內屏幕的操作。而這些操作均來自于移動端的設計標準,比如蘋果IOS設計規范中的標準手勢或者谷歌Mertiral Design中的標準手勢。
△ 移動端常見交互手勢
常見的手勢如上圖,分別為
為了滿足手機屏幕外觀改變,屏內顯示內容越來越多元化的需求,設計師們也在探索屏內手勢的新玩法。
△ android底部導航欄按鍵從左至右分別為:返回上一級、返回主頁、多任務
2017年iPhoneX的發布,正式開啟了全面屏時代。為了替代Home鍵及android底部導航欄,各大手機廠商相繼開始擁抱「全面屏手勢交互」。
在車機系統中,部分汽車制造商也在積極迎接變化,比如理想one采用「三指下滑」的手勢交互替代「返回主頁」的圖標按鍵。
△ 「 三指下滑」表示返回主頁
2019年的Google I/O大會上,新版本Android Q選擇與IOS采用一樣的手勢操作邏輯,即在屏幕下方提供一個指示條,用戶在左側頁面邊緣右滑代表「返回上一級」、提示條區域上滑代表「返回主頁」、提示條區域上滑并懸停代表「多任務」。
△ android系統中的三種全面屏手勢
隨著全面屏手勢在手機端的操作交互上達成一致,相信在不久的將來,也將越來越頻繁的在車機端看到全面屏手勢的「身影」。
當汽車與數字屏幕相遇,如何讓屏幕與內飾結合的更加完美,又能突顯品牌特性,似乎給內飾設計師帶來了許多挑戰與機遇,「一字屏」、「T字屏」、「7字屏」、「旋轉屏」應運而生。
△ 拜騰M-Byte 一字屏
△ 理想one的T字屏
△ 合創007的7字屏
△ 比亞迪王朝系列的旋轉屏
與此同時,因為成本及技術的限制,汽車制造商的量產車型不得不在屏幕上做出妥協。理想one的妥協方案是利用3塊屏幕組合,在視覺上形成「大長屏」的既視感。
要讓3塊屏幕「變」成一塊屏幕,僅僅在視覺上做足功夫顯然還不夠,多屏聯動手勢交互也不能「缺席」。
事實上,多屏聯動手勢交互依舊來源于IOS及android系統中的標準手勢,它將不同的手勢進行組合,并與頁面聯動顯示,形成了多屏聯動手勢。
理想one在停車模式下,用戶長按并向左滑動,即可將副駕娛樂屏上的信息「甩動」至中控屏。
天際ME7不僅有3塊屏幕組合而成的前排「一字屏」,還有2塊后排乘客娛樂屏,5屏聯動的手勢交互,天際采用「手勢+屏幕顯示」來解決。
在中控屏、副駕娛樂屏和后排娛樂屏上采用五指抓取手勢進入多屏互動頁面,比如想把中控屏上的內容分享給副駕娛樂屏,第一步是單擊選中副駕娛樂屏,第二步按住并拖動中控屏至副駕娛樂屏位置,第三步在副駕娛樂屏中點擊確認。
視頻版交互演示:https://v.qq.com/x/page/w08791lhqus.html
通過隔空手勢接聽或者掛斷電話,這似乎是科幻電影中才有的情節。但正如開篇所說,車內屏幕數量增多,尺寸加大的同時「駕駛者分心」的機率也增加了,盲操手勢與隔空手勢的出現,是解決這個痛點的一種嘗試。
目前量產的汽車中,盲操手勢主要是通過標準手勢與聲音反饋的組合來實現。
比如在理想one中,用戶在空調屏上左右滑動可以調節風量,上下滑動調節溫度,且系統通過聲音反饋告知用戶操作成功與否。
與盲操手勢相比,隔空手勢似乎科技感十足,備受汽車制造商的青睞,我們不僅可以在各種概念車上窺見它的蹤影,在君馬SEEK上,也可以實際操作一番。
君馬SEEK提供8種隔空手勢。
△ 左圖:接聽電話 右圖:掛斷電話
△ 左圖:上一曲 右圖:下一曲
△ 左圖:音量升高 右圖:音量降低
△ 左圖:音樂播放/暫停 右圖:玫瑰花
與君馬SEEK相同,寶馬提供「向左」手勢代表上一曲、「向右」手勢代表下一曲,「yeah」手勢代表播放或暫停。
但在許多其他操作上,寶馬與君馬的手勢操作則各有特色。
君馬SEEK使用手掌的正面與反面來區分不同的操作,正面表示接聽電話·/音量增加,反面表示拒聽/音量降低。
寶馬則選擇向屏幕方向點擊代表接聽電話,手掌向右揮動代表拒聽電話,手指順時針畫圈代表音量增加,手指逆時針畫圈代表音量降低。
在倒車影像中,手指向右揮動代表調整視角。
△ 圖片來源于「汽車界的扛把子」的短視頻《寶馬手勢控制詳細演示》
在手勢交互上,拜騰也交出了自己的「成績單」。
拜騰的手勢識別共五種,手掌向下激活手勢識別,手掌向上啟動主頁面,手指移動代表移動光標,ok手勢代表確定,五指捏合可拖拽內容。
△ 圖片來源于太平洋汽車網《拜騰Concept手勢感應系統操作演示》
這些高大上的技術看起來令人興奮,但在實際使用的過程中,依舊存在識別范圍有限、識別精度不靈敏、識別后的響應速度慢等等問題,而各個廠家的手勢識別沒有形成統一的標準,且沒有大規模在在用戶中進行推廣,必然會增加用戶的學習成本。
手勢識別對用戶來說是「真香」還是「雞肋」,相信時間會給出答案。
參考文獻:
汽車內手勢的交互設計,是一個有趣又好玩的課題,但如何讓這個課題在好玩但同時易用、好用,恐怕只有設計師不斷思考,并不斷采用一些用戶測試的方法進行驗證才能獲得答案。
文章來源:優設 作者:點滴DESIGN
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
宋體字可以說是我們現在最常用的字體之一,一方面他與黑體一樣,具有非常良好的可讀性和易辨性,另一方面,他又比黑體更具有歷史感和東方韻味,我們可以看到很多的教材、書籍內文或者官方文件,都是用的宋體字,甚至許多設計都會用一些比較有表現力的宋體字作為標題。所以可想而知,學習設計宋體字對我們的幫助有多大。正所謂欲知大道,必先知史。所以在講如何設計宋體字之前,我們先來扒一扒宋體字的歷史吧。
雖然說宋體字叫做宋體字,但是如果要追溯宋體字的起源,我們還得從唐朝說起。
唐朝時期,佛教在中國開始盛行開來,唐朝皇帝甚至派出唐僧師徒四人前往西天取經。
于是便出現了「抄經生」這種人肉印刷機。這篇經文便是當時唐朝的抄經生所抄寫的,他們需要使用規整統一的楷體,文字的開頭在同一水平線,而且每一列的字數統一規定為17或者19個字,方便字數的統計,像這一篇經文每一列就是17個字。
可是即便出現了大量的抄經生,依舊滿足不了人們對經書的需求。于是聰明的中國人開始印刷經書,將經文刻在木板上,就可以實現大量的印刷了。
可是楷書刻起來是很不方便的。一方面,書法家寫的楷書講究起承轉合、抑揚頓挫,不同的人寫出來的字風格差異十分明顯,例如顏真卿和趙孟頫他們所寫的「宋」字就明顯不同,即便用筆臨摹都很難了,更別說雕刻出來了。
另一方面楷體由于是書寫的字體,所以大多數筆畫都是帶有弧度的,而在木板上刻字,曲線是非常難刻的。
于是他們逐漸將曲線刻成直線,把筆畫的弧形特征降低,也將楷體中相同的筆畫進行規范了,這樣的字體便是宋體字的前身。
我們可以看一下宋朝時期的刻本,這是南宋時期陳宅經籍鋪所刊刻的《朱慶馀詩集》。這時,撇、捺等筆畫的彎曲程度大大降低了,而豎筆和橫筆也基本上變成筆直的直線了。不過宋朝時期刻本體的橫畫依舊是傾斜的,從中依然能很明顯地看到楷體的痕跡。那么為什么宋體字會形成橫細豎粗,橫畫后帶三角形飾角的字形呢?
那是因為刻字的木板上是帶有木紋的,如果垂直木頭的紋理刻的話,筆畫會比較容易斷,需要加粗一些。而如果是順著木紋刻的話,就沒那么容易斷,所以可以相對細一些??墒菫槭裁词菣M畫細,豎畫粗呢?反過來不行嗎。
那是因為在大多數的漢字中,橫畫都是比豎畫多的。上海交大的郭曙綸教授對20902個漢字進行了統計,發現這些漢字的總筆畫數量多達268479個,而其中橫畫有82682個,占30.8%,而豎畫有51459個,占19.2%??梢?,在漢字中橫畫是比豎畫多的。所以如果將橫畫刻粗,豎畫刻細的話,可能會使得字體過擠而不美觀。
雖然說橫畫順著木紋,比較不容易斷,可是橫畫的兩端還是會比較容易磨損的,所以工匠們一般會將橫畫的兩端稍微刻大一些,形成飾角。
在明朝,宋體得到了進一步的簡化,原本復雜精細的刀刻技法簡化成了橫、豎和斜三種,所以刻字工匠的門檻大大降低了,宋體字得到了真正的普及。我們同樣來看一下明朝時期的刻本,這是明朝時期汲古閣刻印的《道德指歸論》,這個時候的宋體橫畫已經基本變成水平了,雖然筆畫依舊比較張揚,但是已經少了許多楷體的影子。所以從明朝時期開始的刻本體才能算作真正的宋體。
也是在明朝時期,宋體字傳到了日本,所以現在日本將宋體字稱為明朝體。
清朝是刻本最多的一個朝代,而宋體字在中國真正被確定統一稱為「宋體字」也是發生在清朝。
了解了宋體字的歷史后,我們可以發現宋體字的意義并非只是美觀和易讀而已,他是經過中華民族近千年傳承、優化和改良的文化結晶,他的身上有著厚重的文化氣息。也難怪中國、日本、韓國等受中華文化影響的國家會對宋體有獨特的偏愛。接著我們就正式進入設計宋體字的教程部分,首先我們來了解一下宋體字的主要特征。
從楷體字轉變為宋體,主要產生了三個特征,第一個是橫平豎直,也就是說橫畫是水平的,豎畫是垂直的。第二個特征是橫畫比較細,豎畫比較粗。第三個特征是筆畫上出現了三角形的裝飾角。
可是隨著字體設計的發展,對于宋體的定義已經越來越模糊了。例如上面的這三種字體,雖然他們不完全滿足宋體的特征,可是它們都能算作是宋體。所以我們也不需要對宋體下一個死定義,免得我們在設計字體的時候被定義所束縛住了。
可是仿宋體是不能夠算是宋體字的。我們看仿宋體是不是覺得他和宋朝時期的刻本非常像呢?因為仿宋體是在民國時期,丁善之和丁輔之模仿宋刻本所設計出來的字體,所以仿宋體模仿的是宋朝刻本,而非宋體字,那么仿宋體當然也就不能算在宋體的行列里了。
接著我們來分析一下宋體字的氣質。由于宋體誕生于明朝,具有非常悠長的歷史,而黑體是在民國時期才產生的,所以宋體相對于黑體更能體現傳統感、文化感的氣質屬性。
所以我們做現代風格的設計的時候,可以使用黑體。
而做比較具有傳統風格的設計則可以用宋體。當然也并非說宋體就沒辦法做現代感的設計,通過對宋體體飾和中宮的設計,我們完全可以做出一款現代型的宋體。
先來說一下中宮,我們在之前的教程里說過,中宮越大,越顯現代感,而中宮越小,則越有傳統感。在宋體里也不例外。
我們再來看看這兩個「東」字,很明顯也是左邊的「東」字更現代一些,而右邊的「東」字傳統一些。這兩個字的區別在于體飾的不同。體飾越少越簡潔,宋體就越顯現代;體飾越多越復雜,就越顯傳統。
另外幾何形的體飾也會給宋體帶來現代感。
而傳統宋體字的體飾則是具有手寫感的,線條比較圓滑。
根據體飾和中宮的不同,我們可以大致地將宋體分為三大類。中宮小、體飾多且具有手寫感的宋體歸類為傳統型宋體,中宮大、體飾少且為幾何體飾的則歸類為現代型宋體。而具有一定手寫感的體飾,且中宮偏大的宋體,則歸類為中間型的宋體。
除了中宮和體飾之外,我們還經常調整筆畫粗細去適應宋體字不同的用途。首先我們先來講講正文的宋體。一般正文的字號都是比較小的,如果橫畫過細的話,會使得橫畫幾乎看不見了,而如果橫畫過粗的話,筆畫又會糊在一塊了,所以為了讓宋體字在小字號下也能清晰的顯示,一般橫畫和豎畫的粗細會控制在1:2到1:3左右,最大一般也不會超過1:4。
不過我們設計正文字體的機會還是比較少的,大多數時候我們都是需要設計比較具有張力的標題字。這個時候我們就可以嘗試拉大橫畫和豎畫的粗細差距。當橫畫和豎畫的粗細差距非常大的時候,可以產生較強的視覺沖擊力。畫面中這三款標題宋體,都用了細橫畫搭配粗豎畫。
有時候我們也可以反其道而行之,將橫畫加粗,讓橫畫與豎畫差不多的粗細。這樣我們就可以獲得一款非常醒目的宋體。這樣的宋體有點像比較粗的黑體,既有醒目的特點,也保留了宋體優雅的屬性。
當然,具有張力的標題宋體也并非一定要通過控制橫豎筆畫的粗細來塑造,通過設計一些有張力的體飾,同樣可以讓宋體字變得具有表現力。設計體飾是設計宋體字非常重要的一個環節,因為宋體字的大多數筆畫是存在許多體飾的,我們除了要將體飾設計得好看之外,更重要的是讓不同的體飾和諧共存。如果一個宋體字里存在的體飾都風格不一,那么這個宋體字看著就會不倫不類了。下面我就給大家介紹一個我比較常用的,設計宋體字體飾的方法。
在做字之前,我們要先確定我們想要做的字體的氣質,是傳統的,還是現代的?文藝的還是可愛的?又或者是其他的氣質。因為我們前面也說到,體飾和中宮都會影響字體的氣質,所以我們必須要確定了氣質之后,才能動手去設計字體的中宮和體飾。
另外還要確定字體的用途,需要比較有張力的標題字體,還是需要具備閱讀舒適性的正文字體,那我們也能確定文字的筆畫粗細。
確定好了風格之后,我們就可以開始設計筆畫了。那么我們先來回顧一下,漢字里的八個基本筆畫,我們可以先把這八個筆畫的體飾特征都設計好了,再去拼湊我們想要的字。
一般來說,我們設計宋體會先從橫畫開始設計。因為確定了橫畫之后,體飾的風格、體飾大小、筆畫粗細等很多東西就都可以確定了。
其實宋體中的體飾都是來源于書法中的頓筆,所以我們來看看書法中,橫畫是怎么寫的,書法中的橫在起筆和收筆處分別有一個頓筆。這兩個頓筆分別對應著宋體橫畫首尾的兩處體飾。對于宋體字來說,橫畫末尾的這個體飾是非常重要的,他對整個字體的氣質影響非常的大。
我們前面已經介紹了這兩種襯角分別具有現代感和傳統感。
而這一個的襯角是一個比較圓潤的圓形,他可以用來做比較可愛的宋體。
這一個襯角和剛剛的就正好相反,非常的非常尖銳,適合用來做比較恐怖的宋體。
還有一點要注意的是,如果豎畫越粗的話,橫畫的襯角一般也要相應的變大一些。
因為宋體的橫畫本來就已經很細了,如果襯角還非常小的話,橫畫很容易就會被忽略掉了,橫畫末端的這個三角形起到了一定強調橫線的作用。當然如果是故意要設計成小襯角或者無襯角的話就另當別論了。
橫畫做好之后,就可以開始設計豎畫了。在書法中,豎畫在起筆處會有一個頓筆,而收筆的地方會稍微往左側偏一些,這樣分別形成了宋體中豎畫起筆和收筆的兩處體飾。
那么我們應該怎么用橫畫推導出豎畫呢?橫畫和豎畫關聯度最大的地方在橫畫三角形襯角和豎畫上方襯角的這個地方。例如這一組都是直線加切角。
而這組都是曲線加圓角。
另外我們還能將這兩個地方給聯系起來,因為他們都是起筆的位置。如果橫畫的起筆是水平的話,那么豎畫的起筆就應該是垂直的。
而如果橫畫的起筆是往外擴的話,那么豎畫的起筆也可以往外擴張。
我一般還會將豎畫的起筆和收筆的的地方關聯起來,如果起筆是垂直的,那么收筆我也會設置成垂直的。
而如果起筆往外擴的話,那么收筆我也會往外擴形成書寫曲線,這樣整個豎畫能看起來平衡一些。
接著來設計橫折。書法中在這個轉折的地方會有一個頓筆。所以在宋體的橫折處也會形成一個裝飾角。
其實橫折這個筆畫在設計好橫畫和豎畫之后基本就已經出來了。只要將他們組合在一起,然后將橫畫的襯角往回縮小一些,橫折就做好了。
講完了橫折我們順便也講一下這種口字的結構好了??谧纸Y構由剛剛做好的橫折加上一個豎線和一個去掉三角襯角的橫線組成。然后我們需要做一些細微的調整。豎筆體飾的這個地方需要往上收一些,不要漏出來,這樣的筆畫看著能干凈一些。
然后豎畫入筆的地方也要往上提一些,讓左右兩邊的體飾能夠平衡。
最后加上橫畫,把襯角的部分裁去,注意兩個豎線需要出頭一些。這個口字就完成了。
然后來做撇和捺。書法里的撇起筆的地方有一個頓筆,所以宋體里,撇有一處體飾。
書法里捺則在起筆和收筆處各有一處轉折。所以宋體里,捺則有兩處體飾。
撇基本上可以從豎線輕易地推導出來,因為他們的起筆都是一樣的,只要稍微調整一下起筆的角度就可以了。
而捺與撇是正好相反的,起筆細,收筆粗,所以捺的起筆需要縮小一些,但是需要保證這兩個地方是相同的。而捺的收筆是一個比較獨立的地方,只需要風格保持大致一致就好了。
接著來做提。在書法中,提的起筆一般是會有一個頓筆的,這一個頓筆與豎的起筆的頓筆是類似,所以在宋體中,提的起筆會有一個與豎類似的體飾。
提與豎起筆的體飾是差不多的,只是方向不同而已。
最后就只剩下點和鉤兩個基礎筆畫還沒設計了。這兩個筆畫和別的筆畫之間的聯系不太大,同樣也只需要保持整體筆畫風格一致就好了。不過點和鉤之間卻存在著一定的聯系的。最主要的是體現在這個地方,如果是尖角,那么點和鉤最好都統一為尖角。
而如果點是圓滑過渡的,那么鉤最好也是圓角。
另外還有如果點的這個位置是比較飽滿的話,那么鉤轉折的位置也應該設計得飽滿一些。
而如果是瘦瘦的點,鉤轉折的位置也要相應的瘦一些。
最后還有一個需要統一的地方,就是撇、點、鉤等筆畫的收筆必須要保持一致??梢允菆A角、還是切角、尖角或者是其他特殊的角,收筆的大小也應該統一。
不過我們設計宋體字時,也并非一定要百分百遵循這一套設計方法,因為這一套設計理論是結合書法所推導出來的,而隨著時代的發展,宋體字的形式和定義也不斷被拓寬,例如一些比較新型的宋體,都會省略掉豎、撇、捺等筆畫的體飾,讓字體顯得更簡潔一些。所以如果大家想做一些比較創新的宋體字,而非傳統嚴謹的字體的話,大可以放開手腳去設計,最終只要保證美觀和和諧統一就好了。
我們在將所有筆畫都設計完之后,就可以將筆畫拼起來了,可是如果我們設計的筆畫比較沒有特點,最后拼湊出來的字體也就顯得有些中規中矩,缺乏視覺張力。那么接下來我就給大家介紹幾個讓宋體字比較有張力的常用方法。
第一個是在宋體字的筆畫之間加入連接線,模擬寫字的連筆效果。
由于宋體字是用刀刻出來的字,基本上是不會有連筆的存在,而加入連筆線條就可以緩和宋體字刀刻的僵硬感,讓文字顯得更靈動。
第二個方式是將設計好的筆畫松散的排列。
因為宋體具有文藝的氣質,而將筆畫松散地排列能夠體現一種慵懶的文藝感,和宋體的氣質是非常契合的。
不過這種方式最好能與詞義吻合,例如團圓這個詞應該是筆畫凝結在一起更能符合團圓的詞義,像這樣做得松松垮垮的味道就有些不太對了。
第三個方式是省略橫畫。由于宋體字存在著三角襯角,所以即便省略掉了橫線,依舊能夠通過三角襯角判斷橫線的位置。
所以省略橫畫對宋體的識別度影響不大,并且能夠增加宋體字的圖形感。
第四個方式是斷筆。
剛剛我們講到了宋體存在著三角襯角,所以省略掉橫畫也不會過多的影響識別度。那么在斷筆這里也是一樣的道理,我們最好選擇斷開橫畫,因為這樣對字體識別度的影響最小。
也許有的人聽到這里會覺得,這才是課程的重點。其實并不是的,這里教給大家的四個增加張力的手法只是輔助工具而已,不是說我先隨便瞎設計一個字體,然后再套用這幾個方法去增加形式感,我認為這樣的方式只是在遮丑而已,而作為設計師的我們更應該追求骨骼和體飾的美感,而非一味遮丑。那么教程部分就到這里結束,下面給大家示范一個案例吧。
我們這節課的案例就是做韋禮安這首貓咪共和國的單曲封面。這是我從MV開頭截的圖。我們可以看到MV中貓咪共和國這五個字是手寫的,給人一種可愛隨意的感覺。那么我們這節課就嘗試用宋體字來體現這種感覺。
那么我們對這款字體的定位就很明確了,是一款可愛的標題字體。
我們先在屏幕上打上貓咪共和國五個字作為字體骨骼的參考。這里我選擇了思源宋體,因為思源宋體是一款現代型的字體,中宮比較大一些。太過緊湊的中宮不適合我們塑造可愛、隨意的感覺。另外一個很重要的原因是,思源宋體雖然高貴,但是免費,如果我們改動的程度不大,也不會造成侵權。
為了讓字體更憨一點,我們可以將文字壓扁一點點,營造出一種老子一米五的感覺。然后就可以降低透明度,開始在這個參考骨架上秀一波操作了,接下來我們就一個筆畫一個筆畫地來設計。
首先因為是標題字體,所以我們希望做一個橫畫和豎畫都差不多粗的宋體,這樣會比較醒目一些。然后因為氣質是可愛的,所以我把體飾設置成圓圓的,胖胖的。
我們用橫畫推導出豎畫。體飾方面基本上就直接照搬了橫畫的體飾,因為橫畫的風格很明顯了,豎畫保持一致就可以了。
接著做橫折。我們先將橫畫和豎畫湊一起看看。這樣會有兩個比較大的問題,一個是豎線的體飾凸出來了一塊,另一個是橫畫和豎畫的襯角疊加在一塊顯得太大了。所以我們需要將襯角縮小一些。
接著做口字結構,我們將豎畫放好之后,發現不用調整也挺平衡的,所以我們就直接用這一個口字。
然后撇和捺的起筆我們也可以直接用豎畫的起筆推導出來。
值得注意的是,我們可以看一下這個撇,為了凸顯這個筆畫的可愛,所以我們筆畫的粗細變化其實是很小的,為的是讓收筆的地方比較鈍一些,顯得更人畜無害。
同樣為了營造字體可愛的氣質,我將捺的收筆也設計成圓弧收筆,而并非普通宋體的尖銳收筆。
接下來我們應該是要做提筆畫的,可是我們發現這五個字里并沒有提,所以我們就跳過他,直接做點和鉤了。同樣為了保證風格的一致,這個點的粗細變化也不大,而且頭特別鈍。
點和鉤之間是有關聯的,這三組地方分別互相對應。
① 端點應該都比較大,比較鈍一些;
② 圓滑地過渡;
③ 屁股的地方比較飽滿一些。
將做好的筆畫放上去,接著還需要做一些調整,因為我們現在用的還是思源宋體的骨架,這個骨架和我們設計的筆畫并不一定搭。我對字面大小,視錯覺等進行了一定的修正,然后還將中宮稍微擴大了一些。這時候我們會發現,調整過后的這組字依然顯得太過正經,還是擺脫不了思源宋體正文字的屬性,而我們想做的字應該是可愛、慵懶的標題字。
不知道大家還記不記得我們剛剛講的宋體字四種增加張力的套路。很明顯松散筆畫這種方式最適合隨機慵懶的感覺,那么我們來試試看。
我們先將這五個字的字距拉開一些,方便我們調整筆畫。然后將筆畫松散地排列開。
接著我們還需要做一些調整,這樣看起來太粗糙了。我們將點、撇、捺等筆畫調短一些,讓他們具有點的感覺。因為點的構成具有隨機和活潑的氣質。
然后將重心往下壓,因為重心靠下的字體會顯得比較憨一些,那么我們這一組字就完成了。
最后我們用這個字來做一個版面,先建立一個單曲封面125mm*125mm的畫板,并設置5mm的頁邊距和7*7的網格。
然后我們放入一張貓的照片作為版面的主體,占據右下角的5.5欄。
接著我們將做好的字體放在左上角,和右下角的貓做對角線的呼應,可是這么擺放好像還是不夠好玩。
所以我們加入英文和線條做成一個文字組合。
最后在版面的左下角加入其它信息,這個單曲封面就做好了。
效果還不錯吧。
最后我們來總結一下這節課。首先我們給大家扒了一下宋體字的歷史,知道了宋體字誕生于明朝,可是最早能夠追溯到唐朝。接著分析了宋體字的特征和氣質,宋體字相較黑體字具有傳統、文化的屬性,可是也能通過對體飾、中宮的控制,設計出具有現代感的宋體。然后我們教給了大家一套設計宋體字體飾的方法,最后是四個增加宋體字張力的常用手法。那么我們這節課就到這里,我是千樹,我們下次再見。
文章來源:優設 作者:研習設
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
為什么需要額外的類型檢查?
TypeScript 只在編譯期執行靜態類型檢查!實際運行的是從 TypeScript 編譯的 JavaScript,這些生成的 JavaScript 對類型一無所知。編譯期靜態類型檢查在代碼庫內部能發揮很大作用,但對不合規范的輸入(比如,從 API 處接收的輸入)無能為力。
運行時檢查的嚴格性
至少需要和編譯期檢查一樣嚴格,否則就失去了編譯期檢查提供的保證。
如有必要,可以比編譯期檢查更嚴格,例如,年齡需要大于等于 0。
運行時類型檢查策略
定制代碼手動檢查
靈活
可能比較枯燥,容易出錯
容易和實際代碼脫節
使用校驗庫手動檢查
比如使用 joi:
import Joi from "@hapi/joi"const schema = Joi.object({ firstName: Joi.string().required(), lastName: Joi.string().required(), age: Joi.number().integer().min(0).required()});
靈活
容易編寫
容易和實際代碼脫節
手動創建 JSON Schema
例如:
{ "$schema": "http://json-schema.org/draft-07/schema#", "required": [ "firstName", "lastName", "age" ], "properties": { "firstName": { "type": "string" }, "lastName": { "type": "string" }, "age": { "type": "integer", "minimum": 0 } }}
使用標準格式,有大量庫可以校驗。
JSON 很容易存儲和復用。
可能會很冗長,手寫 JSON Schema 可能會很枯燥。
需要確保 Schema 和代碼同步更新。
自動創建 JSON Schema
基于 TypeScript 代碼生成 JSON Schema
-- 比如 typescript-json-schema 這個工具就可以做到這一點(同時支持作為命令行工具使用和通過代碼調用)。
-- 需要確保 Schema 和代碼同步更新。
基于 JSON 輸入示例生成
-- 沒有使用已經在 TypeScript 代碼中定義的類型信息。
-- 如果提供的 JSON 輸入示例和實際輸入不一致,可能導致錯誤。
-- 仍然需要確保 Schema 和代碼同步更新。
轉譯
例如使用 ts-runtime。
這種方式會將代碼轉譯成功能上等價但內置運行時類型檢查的代碼。
比如,下面的代碼:
interface Person { firstName: string; lastName: string; age: number;}const test: Person = { firstName: "Foo", lastName: "Bar", age: 55}
會被轉譯為:
import t from "ts-runtime/lib";const Person = t.type( "Person", t.object( t.property("firstName", t.string()), t.property("lastName", t.string()), t.property("age", t.number()) ));const test = t.ref(Person).assert({ firstName: "Foo", lastName: "Bar", age: 55});
這一方式的缺陷是無法控制在何處進行運行時檢查(我們只需在輸入輸出的邊界處進行運行時類型檢查)。
順便提一下,這是一個實驗性的庫,不建議在生產環境使用。
運行時類型派生靜態類型
比如使用 io-ts 這個庫。
這一方式下,我們定義運行時類型,TypeScript 會根據我們定義的運行時類型推斷出靜態類型。
運行時類型示例:
import t from "io-ts";const PersonType = t.type({ firstName: t.string, lastName: t.string, age: t.refinement(t.number, n => n >= 0, 'Positive')})
從中提取相應的靜態類型:
interface Person extends t.TypeOf<typeof PersonType> {}
以上類型等價于:
interface Person { firstName: string; lastName: string; age: number;}
類型總是同步的。
io-ts 很強大,比如支持遞歸類型。
需要將類型定義為 io-ts 運行時類型,這在定義類時不適用:
-- 有一種變通的辦法是使用 io-ts 定義一個接口,然后讓類實現這個接口。然而,這意味著每次給類增加屬性的時候都要更新 io-ts 類型。
不容易復用接口(比如前后端之間使用同一接口),因為這些接口是 io-ts 類型而不是普通的 TypeScript 類型。
基于裝飾器的類校驗
比如使用 class-validator 這個庫。
基于類屬性的裝飾器。
和 Java 的 JSR-380 Bean Validation 2.0 (比如 Hibernate Validator 就實現了這一標準)很像。
-- 此類 Java EE 風格的庫還有 typeorm (ORM 庫,類似 Java 的 JPA)和 routing-controllers (用于定義 API,類似 Java 的 JAX-RS)。
代碼示例:
import { plainToClass } from "class-transformer";import { validate, IsString, IsInt, Min } from "class-validator";class Person { @IsString() firstName: string; @IsString() lastName: string; @IsInt() @Min(0) age: number;}const input: any = { firstName: "Foo", age: -1};const inputAsClassInstance = plainToClass( Person, input as Person);validate(inputAsClassInstance).then(errors => { // 錯誤處理代碼});
類型總是同步的。
需要對類進行檢查時很有用。
可以用來檢查接口(定義一個實現接口的類)。
注意:class-validator 用于具體的類實例。在上面的代碼中,我們使用它的姊妹庫 class-transformer 將普通輸入轉換為 Person 實例。轉換過程本身不進行任何類型檢查。
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
為什么要做數據可視化?
在一個設計項目里,
到底要從哪一個角度切入,才能經得推敲?
每個數據可視化,
模擬美國1790-2016 移民的時代樹輪
作者從自然中的樹輪提取靈感,把樹的生長遷移到移民變化上,發現了美國通過類似的移民過程。
https://web.northeastern.edu/naturalizing-immigration-dataviz/
這個可視化形式非常經典,條紋代表了自19世紀中期以來每年的全球平均氣溫,通過網頁的相互作用,你還能看到不同國家不同地區在這段時間的溫度變化。,
現居上海,在澎湃新聞擔任數據可視化設計師。
自學編程兩年多,最初是為了做更酷的數據可視化作品,誤打誤撞放置了十款設計小工具,變成了模仿的設計玩具制造玩家,希望用編程去解鎖設計/數據可視化的更多可能性。
●
為理清垃圾分類規則,亞賽及團隊從上海市垃圾分類查詢平臺上篩選了2055件物品的垃圾分類信息,看可視化教你如何分類垃圾。
項目封面,垃圾從屏幕上方掉落,通過鼠標可以進行交互。
世界杯落幕,一個月來32支球隊打入了169粒進球。如果俯瞰足球場,將所有進球在一張圖上繪出,有某種絕妙的,驚險的,烏龍的瞬間?
亞賽大學專業是廣告學,畢業后卻成為數據可視化設計師,在她看來,數據可視化并同時是“圖表”,而是用設計和編程描述數據背后的故事,發現世界的渠道。如何展示數據,如何跟觀眾講這個既定事實故事,都是設計師需要考慮的。
紅色向上為相對積極,藍色行下為相對消極,每根柱子的長度代表情緒的大小,通過3000多條微博看到她在微博內容背后自己的情緒斗爭。
結合她發微博的時間制作了微博發布時間情況,用花瓣作為視覺呈現,真切意識到患者脆弱的無力感。
在這里你能看到117年氣溫的變化
●
為什么要數據可視化?
1.我們利用視覺獲取的信息量,其實遠遠超過別別的感官要多層次。
2.可視化將會讓觀眾更加直觀全面看待事實故事
3.人類大腦對記憶能力的限制
垃圾分類可視化手冊
169球回顧俄羅斯世界杯
●
數據分析53027條留言背后
抑郁癥患者的自救與互助
02
數據可視化
創作的7個步驟
景點事件:某種前幾天的女排十一連勝,就可以提前找數據做一個梳理類的題。
熱門話題:有的話題是社會持續關注的起點,可以從深度報道,學術研究等不同管道持續關注。
關注來源:習慣性地關注一些信息來源,某些智庫,政府網站,外國網站等等。
1.獲取數據,無所謂是來自文件,磁盤亦或者網絡等;
2.分析數據結構,分類排序;
3.過濾,去掉所有不感興趣的數據;
4.綜合使用數學,統計,模式識別等方法來挖掘出一些特征數據;
5.選擇某種樹狀圖,列表,樹等的可視化模型來替換數據;
6.精煉基本表示法,使數據插入的更清楚,預期視覺效果;
7.添加一些用于控制或操作數據的交互方法。
●
這是亞賽做過一個關于春節禁放煙花的選題,把某些城市的除夕中午12點到春節中午12點變成一朵24片花瓣(代表24小時)的煙花,對比2017年和2018年兩年的數據。
通過環境質量數據來看煙花禁放政策下的效果,看到不同地區不同政策帶來的影響。
詳細案例:https : //wangyasai.github.io/Work/firework.html
03
文章來源:站酷 作者:最畢設設計媒體
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
如今,Page Speed(頁面速度)的意義非凡。
自從Google改變Googlebot's的算法以高度支持快速,適合移動設備的網站以來,擁有快速網站變得越來越重要。如果這還不夠好,用戶通常會花更少的時間,轉化率也會更低,你的網站體驗越慢,用戶的轉化率就越低。
什么是Page Speed
Page Speed是將內容完全加載到網頁上所花費的時間。
對于任何給定的用戶來說,頁面緩慢的原因可能有很多,你的用戶可能正在火車上,通過信號弱的隧道,或者他們的互聯網速度很慢。
通過遵循最佳實踐,我們至少可以通過確保我們已經做了最好的工作來緩解問題。
現在你知道它是什么了,下面我就來教你如何提高頁面速度。
注意:這些是按難度順序列出的。在某個時候,你將需要開發人員來幫助優化你的網站。
1.使用CDN
CDN是內容傳輸網絡的縮寫。使用CDN可以讓你有效地訪問全球數百臺小服務器,這些服務器為你提供網站的副本,大大減少了你的網站獲取時間。如果你沒有使用CDN,你的網站的每一個請求(包括圖片、CSS和JavaScript)都會被緩慢地傳送到你的服務器上。
根據HTTPArchive中的4.68億個請求,48%的請求不是來自CDN。那是超過2.24億的請求,如果他們花幾分鐘的時間給自己的網站添加一個CDN,速度可能會超過50%。
一定要檢查你的CDN配置是否正確——在你的CDN中緩存丟失意味著CDN必須向你的源服務器請求資源,這就違背了使用CDN的初衷!所以,你的CDN必須要有一個正確的配置。
2.啟用GZIP壓縮
在一些CDN上,GZIP壓縮只是一個標有 "啟用壓縮 "的復選框。這大概會減少一半的文件大小,你的用戶需要下載文件才能使用你的網站,你的用戶會因此而喜歡你。
3.使用較小的圖像
這意味著既要降低分辨率(例如,攝像頭的輸出從4000x3000像素減少到網絡的1000x750),又要通過壓縮文件來減小尺寸。
如果你的網站使用WordPress,則有一些插件會在你上傳圖片時自動為你執行此操作。
在撰寫博客文章時,我個人使用TinyJPG壓縮圖像。
https://tinyjpg.com/
4.減少頁面發出的請求數
目標是減少加載頁面頂部部分所需的請求數量。
這里有兩種思維方式,你可以:
通過刪除花哨的動畫或不能改善網站體驗的圖像,減少整個頁面上的請求數量。
或者,你可以通過使用延遲加載來推遲優先級不高的加載內容。
5.盡可能避免重定向
重定向會大大降低網站速度。使用響應式CSS并從一個域為你的網站提供服務,而不是為移動用戶提供特殊的子域。
有些重定向是不可避免的,比如 www-> 根域 或 根域 ->www,但你的大部分流量不應該經歷重定向來查看你的網站。
6.減少到第一個字節的時間
到第一個字節的時間是指你的瀏覽器在發出資源請求后,從服務器接收到第一個字節的數據所花費的時間。
有兩個部分:
在服務器上花費的時間
發送數據所花費的時間
你可以通過優化你的服務器端渲染、數據庫查詢、API調用、負載平衡、你的應用程序的實際代碼以及服務器的負載本身(特別是如果你使用的是廉價的虛擬主機——這將影響你的網站的性能),來改善你在服務器上花費的時間。
你可以使用CDN大大減少發送數據所花費的時間。
7.減少并刪除阻止渲染的JavaScript
外部腳本(特別是那些用于營銷的外部腳本)往往會寫得很差,會阻止你的頁面加載,直到它運行完畢。
你可以通過將外部腳本標記為異步來減少這種影響:
<script async src="https://example.com/external.js"></script>
你還可以延遲加載市場營銷腳本,直到用戶開始滾動為止:
window.addEventListener(
'scroll',
() =>
setTimeout(() => {
// 在此插入營銷片段
}, 1000),
{ once: true }
);
8.縮小CSS和JS
Minifying是指使用工具來刪除空格、換行符和縮短變量名。通常情況下,這將作為構建過程的一部分自動完成。
要縮小JavaScript,請查看UglifyJS。
http://lisperator.net/uglifyjs/
要縮小CSS,請查看cssnano。
9.刪除未使用的CSS
自Chrome 59(2017年4月發布)以來,在Chrome DevTools中可以看到未使用的JS和CSS。
要看這個,打開DevTools,顯示控制臺抽屜(就是點擊Esc時出現的那個煩人的東西),點擊左下角的三個小點,打開 "Coverage",就可以看到。
點擊帶有重新加載圖標的按鈕將刷新頁面,并審核CSS和JS的使用情況。
在Google Chrome瀏覽器中審核初始頁面時,外觀如下所示:
10.定期跟蹤網站速度
在你的網站速度變慢的瞬間,修復網站速度問題就會容易得多。除此之外,如果你把檢查網站速度作為一種習慣,那么修復網站速度慢的問題就會變成一件小得多的事情。
有免費的工具可以監視你網站的速度,其中的兩個是WebPageTest和Google Lighthouse。這些工具的缺點是你需要記住在進行更改之前和之后都必須運行它們。
PerfBeacon是一項服務(由本文的作者創建),該服務定期運行Google Lighthouse,并讓你隨時跟蹤網站的速度。
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
據悉,截至2019年12月31日,肯德基會員數量超過2.15億,必勝客會員數量超過7000萬,相比去年同比增長35%和33%。
付費會員卡持續受到消費者歡迎,在第四季度售出超過300萬張,從付費會員卡項目推出以來已經累計售出1500萬張,尊享卡帶來的銷售占比持續增加。
為什么會KFC付費會員發展如此迅速呢?有哪些值得我們學習的設計點呢?我們今天就來分析下。
上周末,孩子突然想吃肯德基,娃命難違,我們就去了家附近的KFC。點餐的時候,發現有個「親子卡」活動,于是就好奇的了解了一下,看完之后,我就毫不猶豫地加入了親子卡會員。
回到家后,職業病就犯了。開始思考「我為什么會開卡?是什么吸引了我呢?」,簡單做下自我分析。
1. 用戶需求
其實我不算是肯德基的忠實粉絲,吃肯德基的次數比較少,但是如果吃漢堡類的快餐,我首選肯德基。
我兒子才是真正的目標用戶,因為他更喜歡吃肯德基,基本上1~2周就會吃一次。因此當考慮是否開卡時,我認為吃肯德基對我來說是強需求。
2. 消費場景
肯德基線下門店眾多,特別是地鐵、商場等人流量密集的場所。我家附近、孩子周末上課的地方都有肯德基門店,與孩子的生活軌跡重合度較高,到店就餐比較方便,無需外送費等額外消費。因此開卡后不存在消費障礙點。
3. 商品特點
肯德基的商品基本可以說老少咸宜,用戶接受度較高,不會因為口味等問題,讓孩子無法接受。
??
拋開平臺差異等因素,用戶進行開卡決策時,最核心的問題就是「值不值得付費開卡」。這里面包含了2個關鍵因素,會員費和權益價值。
會員費是一定的,變動的是用戶對權益價值的認知。親子卡的權益有什么特點呢?
通過上圖可以看出肯德基的親子卡權益并不復雜,我將權益劃分為四種類型,抽離出一個簡單的權益模型,可以明顯看出權益的分層設計。
開卡權益
作為開卡權益,也是最有吸引力的權益,就是免費享受價值68元的親子桶。而「親子卡」會員費是78元,基本保證了用戶可以「一單回本」,消除了用戶支付「會員費」時的回本擔憂,很容易激發用戶的開卡欲望。
日常權益
激起用戶開卡欲望后,需要通過各種日常權益,提升權益的價值感。又可以促進用戶到店消費,產生二次消費。肯德基采用了低價商品(冰淇淋/蛋撻)周末免費贈送的策略,可以更好的吸引用戶到店使用消費。
關鍵節點權益
特定節日的消費行為,可以減少了用戶的記憶負擔,保證用戶不容易忘記使用消費券。而在消費之后,用戶也會產生獨特的記憶點,提升對KFC的消費好感。另外半價權益進一步增強用戶省錢認知。
推廣權益
我之前偶爾會看到家長和小朋友聚在肯德基舉行生日會,知道在肯德基有這項服務,但從未主動了解其中的細節。辦卡之后,我主動了解了權益內容,從而對生日會有了更多的認知。
因此這項權益主要目的,或許是占領用戶心智,鼓勵更多的用戶在肯德基舉辦生日會。
總結下親子卡體驗設計的特點:
開卡立享,增強用戶獲得感
肯德基「開卡立享」的形式,讓用戶認為自己免費吃了一頓,從而提高了開卡權益的價值感。同時對于「免費」獲得套餐,用戶也不會太計較親子桶中的商品種類。
如果我們將「開卡立享」權益,換成「再付20元立享88元親子桶」。用戶可能就要考慮「又要付錢,這權益不咋地啊」,「還要再花費20元,總共要花掉98元,這頓飯超支了」等,「桶里有什么呢,是不是我喜歡吃的」等疑問,會增加用戶決策過程中的阻礙點。
特定商品,減少用戶思考
由于肯德基食品的普適性,開卡立享的親子桶食物是特定的,用戶不需要自選。也沒有采用68元的優惠券、折扣等形式。因為特定的套餐可以減少用戶選擇和思考時間,縮短用戶思考路徑長度,避免思考過程中的用戶流失。
權益簡單化,快速決策
親子卡權益數量不多,但是聚焦就餐核心權益,增強對用戶的吸引力,同時方便用戶理解。例如周末免費,半價商品等,里面沒有復雜的計算公式,用戶不需要過多的思考,就可以快速做出決策。
門店推廣,清除開卡障礙點
肯德基到店消費,為產品推廣提供了更多便利條件。當用戶在開卡過程中遇到任何問題,都可以尋找店內工作人員得到快速解決,從而減少了用戶的后顧之憂。例如我當時想要了解下「半價桶」價格是怎樣的,直接咨詢店內人員就解決了。
1. 拼多多&淘寶月卡
同樣的設計也體現在拼多多、淘寶月卡中。面對下沉市場用戶,兩者都將權益簡單化處理,通過簡單直白的無門檻券、優惠紅包作為賣點,主打「回本」、「30天未使用全部退款」等策略,對于平臺新人、忠實用戶都可以形成較強的吸引力,提升用戶開卡轉化率。
2. 天貓會員店
天貓會員店采用的是「券+新人價商品」的策略。
連續包季的會費是25元,而新人價商品的省錢金額基本可以保證用戶「省回會費」。商品定價主要采用1元新人價的形式,基本消除了用戶的價格疑慮,保證用戶不需要各大平臺比價,減少用戶比價過程中的流失。
另外新人價商品主要是普適性很強的生活快銷品,作為生活必需品,可囤貨、消耗快,用戶在商品選擇時不會消耗過多的精力。
用戶一旦開卡后,形成了沉沒成本,每月多種規格的滿減券又可以提升用戶的消費頻率,從而提升商品轉化率。
付費會員在各個行業領域都在快速發展,而且衍生出了多種付費類型,例如主打權益價值、追求豐富權益的淘寶「88會員」、京東「PLUS會員」,主打省錢的拼多多「省錢月卡」、淘寶「紅包省錢卡」,還有「付費會員制」的天貓會員店等。
無論哪種付費會員產品,開卡率都是產品的核心指標。而在體驗設計上,我們需要減少用戶的開卡阻力,增強用戶的權益感知,縮短用戶的思考路徑,從而更好地為商業賦能。
文章來源:優設 作者:子牧設計筆談
世界和技術正在飛速發展,每年都會影響設計趨勢的走向。作為設計師,我們需要了解現有和即將到來的設計趨勢,不斷學習,改進和擴大我們的知識儲備,以便與時俱進。
根據研究、經驗和觀察,我們非常仔細地選擇了2020年應該注意的8種UI / UX設計趨勢。那就讓我們開始吧~
通過對插圖,或者讓插圖進行運動,可以使我們的設計脫穎而出,并使其栩栩如生-增加額外的細節和個性。
微交互完美證明了:著重于細節和發揚這些細節可能會大大改善你的APP的用戶體驗,并將使之更高能/更。
新的Web瀏覽器功能為3D圖形打開了大門,作為設計師可以在現代Web和移動界面中創造和實現驚人的3D圖形。
游戲行業常將創新、和新技術帶入產品設計中。
在AR空間中,有無數令人興奮的體驗機會。AR的UI設計將成為2020年的主要趨勢之一,因此,作為設計師,我們應該做好準備,并主動在創建AR體驗時學習新的工具和原理。
VR / AR技術的增長,以及最流行的設計平臺上顯示的那些優秀的設計告訴我們:設計趨勢可能會使擬物設計在2020年卷土重來,但這一次,它會加入更多現代時尚。
非對稱布局有很大的創造空間,不過創建優秀的非對稱布局需要我們有一定的經驗和時間去處理它。
講故事就是以最佳的信息和創意方式將數據傳輸給用戶。講故事也是一種出色而有效的營銷工具,可以極大地提高你的產品/服務的銷售額。
插畫在產品設計中已經存在了很長時間。最近幾年的發展更是令人矚目。插畫作為非常流行的設計元素,為我們產品的整體UX添加了「自然的感覺」和「人性化的感覺」。插畫也是吸引注意力的焦點:通過對這些插畫進行動效的展示,可以使我們的產品栩栩如生,并使它們脫穎而出-增加更多的細節和個性。
歡迎來到我們的商店!
入職動畫
動效展示的另一個好處是可以吸引用戶的注意力并使用戶與您的產品互動。動畫也是講述您的品牌、產品或服務故事的最有效方法之一。
微交互幾乎存在于每個APP或網站中。每次打開喜歡的APP時,你都會看到它們。例如,Facebook有大量不同的微交互,其中「贊」功能就是一個很好的例子。雖然有時我們甚至不會特意感知到它的存在,因為它非常明顯的、自然的「融合」到用戶界面中去了。但是如果你從界面中刪除它們,你將很快意識到,某些重要的功能丟失了。
菜單切換關閉動畫
標簽欄活動動畫
一般來說,在UI / UX設計中,有時即使很小的更改也可能產生巨大的影響。微交互完美證明了細節和發揚它們可能會大大改善你的APP的整體用戶體驗,并將其置于更高能/更的層次。在每一年,每種新設備都會帶來新的創造全新的微交互的機會,當然,2020年也不例外。
3D圖形幾乎無處不在-在電影,視頻游戲,街頭廣告中。3D圖形是幾十年前才被引入到產品設計中的,從那時起,它已經得到了極大到改善,并得到了高速的發展。移動和網絡技術也在快速增長。新的Web瀏覽器功能為3D圖形打開了大門,我們作為設計師可以在現代Web和移動界面中創建和實現炫目的3D圖形。
3D翻轉菜單
汽車健康報告用戶界面
創建3D圖形并將其實現到Web和移動界面中需要一些特定的技能和大量的工作,但是通常結果是非常有意義的。
Apple AirPods Pro登陸頁面
3D圖形以一種更具交互性和吸引力的方式來展示產品或服務:例如,可以以360度演示方式查看3D圖形,從而改善了產品的用戶體驗。
在2020年,更多的品牌將使用3D模型來展示產品或服務,打通線上線下,以模擬現實世界(店內)的購物體驗。
2019年對于VR來說,是重要的一年。在過去的幾年,我們見證了VR技術的發展和其不可思議的效果,其中大部分是在游戲行業。游戲行業通常會首先在產品設計中引入創新和新技術。研究證明VR也不例外,2019年Oculus Quest推出后,其他行業也嘗試了很多可能性。Facebook首席執行官馬克·扎克伯格(Mark Zuckerberg)已經測試了令人興奮的手部交互功能,并于2020年初正式宣布了Quest的手部跟蹤更新!
Oculus Quest-手互動功能
PlayStation虛擬現實網站設計
索尼和微軟將在2020年發布其新一代游戲機。這些將為虛擬現實技術帶來很多機遇和增長空間。
過去幾年中,我們看到了AR的許多發展和改進。世界領先的科技公司在AR開發方面投入了數百萬美元,我們應該期望在2020年行業會擴展和發展此項技術。甚至蘋果公司也推出了自己的AR工具包ARKIT 3,以幫助設計人員和開發人員構建基于AR的產品。
ARKit 3 蘋果
公共交通應用
Nathan Riley的植物之家AR概念
在AR空間中,有無數令人興奮的體驗機會。AR的UI設計將成為2020年的主要趨勢之一,因此,作為設計師,我們應該做好準備,并主動在創建AR體驗時學習新的工具和原理。
一般來說,擬物設計是指以逼真的樣式/方式創建的設計元素,以匹配現實生活中的對象。VR / AR技術的增長和最流行的設計平臺(Dribbble,Behance等)上顯示的設計趨勢顯示:擬物設計可能會在2020年卷土重來,但這一次,它會加入更多現代時尚。同時有了一個略作修改的名稱:“新擬物” (也稱為Neumorphism)。
Skeuomorph手機銀行的黑暗模式
音樂播放器
睡眠周期應用程序
我們可能已經注意到:「新擬物設計」代表非常詳細和的設計風格。高光,陰影,發光都被運用在設計中去。他們對細節的關注令人非常印象深刻。這已經啟發了來自世界各地的許多設計師,并且很有可能成為2020年最大的UI設計趨勢。
在過去的幾年中,我們注意到產品設計中大量使用不對稱布局?;?nbsp; 傳統/模板 的布局漸漸消失。2020年將依舊如此,因為這一趨勢將繼續保持。正確使用非對稱布局會為我們的設計增加很多特征、動態和個性,或許它們將不再拘泥于模板。
Limnia高級珠寶首飾網格
卡琳時裝商店
創建非對稱布局時、有很大的創造空間。盡管創建成功的非對稱布局需要一定的經驗和時間、將元素隨機放置在網格上當然是不行的) 此外,應謹慎使用和實現它們-因為我們要始終牢記用戶的需求:我們不希望用戶使用我們產品的時候感到困惑。
故事在產品設計中的用戶體驗中扮演著非常重要的角色??赡軙诘卿涰撁嫔辖洺?吹剿鼈?,作為對品牌,產品或新功能的介紹。講故事就是以最佳的信息和創意方式將數據傳輸給用戶。這可以通過「版權(品牌)保護」與「強大而平衡的視覺等級」(印刷術,插圖,高質量照片,大膽的色彩,動畫和交互式元素)混合來實現。
講故事就是以最佳的信息和創意方式將數據傳輸給用戶。
「本周青年實驗室」頁面故事動畫
講故事確實有助于在品牌和用戶之間建立積極的情感和關系。講故事還可以使您的品牌更令人難忘,并使用戶覺得他們是我們產品或服務的一部分,因此他們希望與他們建立聯系。話雖如此,講故事還是一種出色而有效的營銷工具,可能會大大提高您的產品/服務的銷售額。作為非常成功的工具,講故事將在2020年繼續并擴大。
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
文章來源:站酷 作者:一個辛普森
了解如何使用JavaScript中的Cache API緩存資源。
Cache API允許服務工作者對要緩存的資源(HTML頁面、CSS、JavaScript文件、圖片、JSON等)進行控制。通過Cache API,服務工作者可以緩存資源以供脫機使用,并在以后檢索它們。
檢測Cache支持
檢查 caches 對象在 window 中是否可用。
let isCacheSupported = 'caches' in window;
caches 是 CacheStorage 的一個實例。
創建/初始化Cache
我們可以使用 open 方法創建一個具有 name 的緩存,這將返回 promise。如果緩存已經存在,則不會創建新的緩存。
caches.open('cacheName').then( cache => {
});
你不能訪問為其他源(域)設置的緩存。
你正在創建的緩存將為你的域創建。
你可以為同一個域添加多個緩存,可以通過 caches.keys() 訪問。
將項目添加到緩存
可以使用三種方法 add,addAll,set 來緩存資源。 add() 和 addAll() 方法自動獲取資源并對其進行緩存,而在 set 方法中,我們將獲取數據并設置緩存。
add
let cacheName = 'userSettings';
let url = '/api/get/usersettings';
caches.open(cacheName).then( cache => {
cache.add(url).then( () => {
console.log("Data cached ")
});
});
在上面的代碼中,內部對 /api/get/usersettings url的請求已發送到服務器,一旦接收到數據,響應將被緩存。
addAll
addAll 接受URL數組,并在緩存所有資源時返回Promise。
let urls = ['/get/userSettings?userId=1', '/get/userDetails'];
caches.open(cacheName).then( cache => {
cache.addAll(urls).then( () => {
console.log("Data cached ")
});
});
Cache.add/Cache.addAll 不緩存 Response.status 值不在200范圍內的響應,Cache.put 可以讓你存儲任何請求/響應對。
put
put 為當前的 Cache 對象添加一個key/value對,在 put 中,我們需要手動獲取請求并設置值。
注意:put() 將覆蓋先前存儲在高速緩存中與請求匹配的任何鍵/值對。
let cacheName = 'userSettings';
let url = '/api/get/userSettings';
fetch(url).then(res => {
return caches.open(cacheName).then(cache => {
return cache.put(url, res);
})
})
從緩存中檢索
使用 cache.match() 可以得到存儲到URL的 Response。
const cacheName = 'userSettings'
const url = '/api/get/userSettings'
caches.open(cacheName).then(cache => {
cache.match(url).then(settings => {
console.log(settings);
}
});
settings 是一個響應對象,它看起來像
Response {
body: (...),
bodyUsed: false,
headers: Headers,
ok: true,
status: 200,
statusText: "OK",
type: "basic",
url: "https://test.com/api/get/userSettings"
}
檢索緩存中的所有項目
cache 對象包含 keys 方法,這些方法將擁有當前緩存對象的所有url。
caches.open(cacheName).then( (cache) => {
cache.keys().then((arrayOfRequest) => {
console.log(arrayOfRequest); // [Request, Request]
});
});
arrayOfRequest是一個Request對象數組,其中包含有關請求的所有詳細信息。
檢索所有緩存
caches.keys().then(keys => {
// keys是一個數組,其中包含鍵的列表
})
從緩存中刪除項目
可以對 cache 對象使用 delete 方法來刪除特定的緩存請求。
let cacheName = userSettings;
let urlToDelete = '/api/get/userSettings';
caches.open(cacheName).then(cache => {
cache.delete(urlToDelete)
})
完全刪除緩存
caches.delete(cacheName).then(() => {
console.log('Cache successfully deleted!');
})
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
作為一個曾經的Java coder, 當我第一次看到js里面的裝飾器(Decorator)的時候,就馬上想到了Java中的注解,當然在實際原理和功能上面,Java的注解和js的裝飾器還是有很大差別的。本文題目是Vue中使用裝飾器,我是認真的,但本文將從裝飾器的概念開發聊起,一起來看看吧。
通過本文內容,你將學到以下內容:
了解什么是裝飾器
在方法使用裝飾器
在class中使用裝飾器
在Vue中使用裝飾器
本文首發于公眾號【前端有的玩】,不想當咸魚,想要換工作,關注公眾號,帶你每日一起刷大廠面試題,關注 === 大廠offer。
什么是裝飾器
裝飾器是ES2016提出來的一個提案,當前處于Stage 2階段,關于裝飾器的體驗,可以點擊 https://github.com/tc39/proposal-decorators查看詳情。裝飾器是一種與類相關的語法糖,用來包裝或者修改類或者類的方法的行為,其實裝飾器就是設計模式中裝飾者模式的一種實現方式。不過前面說的這些概念太干了,我們用人話來翻譯一下,舉一個例子。
在日常開發寫bug過程中,我們經常會用到防抖和節流,比如像下面這樣
class MyClass {
follow = debounce(function() {
console.log('我是子君,關注我哦')
}, 100)
}
const myClass = new MyClass()
// 多次調用只會輸出一次
myClass.follow()
myClass.follow()
上面是一個防抖的例子,我們通過debounce函數將另一個函數包起來,實現了防抖的功能,這時候再有另一個需求,比如希望在調用follow函數前后各打印一段日志,這時候我們還可以再開發一個log函數,然后繼續將follow包裝起來
/**
* 最外層是防抖,否則log會被調用多次
*/
class MyClass {
follow = debounce(
log(function() {
console.log('我是子君,關注我哦')
}),
100
)
}
上面代碼中的debounce和log兩個函數,本質上是兩個包裝函數,通過這兩個函數對原函數的包裝,使原函數的行為發生了變化,而js中的裝飾器的原理就是這樣的,我們使用裝飾器對上面的代碼進行改造
class MyClass {
@debounce(100)
@log
follow() {
console.log('我是子君,關注我哦')
}
}
裝飾器的形式就是 @ + 函數名,如果有參數的話,后面的括號里面可以傳參
在方法上使用裝飾器
裝飾器可以應用到class上或者class里面的屬性上面,但一般情況下,應用到class屬性上面的場景會比較多一些,比如像上面我們說的log,debounce等等,都一般會應用到類屬性上面,接下來我們一起來具體看一下如何實現一個裝飾器,并應用到類上面。在實現裝飾器之前,我們需要先了解一下屬性描述符
了解一下屬性描述符
在我們定義一個對象里面的屬性的時候,其實這個屬性上面是有許多屬性描述符的,這些描述符標明了這個屬性能不能修改,能不能枚舉,能不能刪除等等,同時ECMAScript將這些屬性描述符分為兩類,分別是數據屬性和訪問器屬性,并且數據屬性與訪問器屬性是不能共存的。
數據屬性
數據屬性包含一個數據值的位置,在這個位置可以讀取和寫入值。數據屬性包含了四個描述符,分別是
configurable
表示能不能通過delete刪除屬性,能否修改屬性的其他描述符特性,或者能否將數據屬性修改為訪問器屬性。當我們通過let obj = {name: ''}聲明一個對象的時候,這個對象里面所有的屬性的configurable描述符的值都是true
enumerable
表示能不能通過for in或者Object.keys等方式獲取到屬性,我們一般聲明的對象里面這個描述符的值是true,但是對于class類里面的屬性來說,這個值是false
writable
表示能否修改屬性的數據值,通過將這個修改為false,可以實現屬性只讀的效果。
value
表示當前屬性的數據值,讀取屬性值的時候,從這里讀??;寫入屬性值的時候,會寫到這個位置。
訪問器屬性
訪問器屬性不包含數據值,他們包含了getter與setter兩個函數,同時configurable與enumerable是數據屬性與訪問器屬性共有的兩個描述符。
getter
在讀取屬性的時候調用這個函數,默認這個函數為undefined
setter
在寫入屬性值的時候調用這個函數,默認這個函數為undefined
了解了這六個描述符之后,你可能會有幾個疑問: 我如何去定義修改這些屬性描述符?這些屬性描述符與今天的文章主題有什么關系?接下來是揭曉答案的時候了。
使用Object.defineProperty
了解過vue2.0雙向綁定原理的同學一定知道,Vue的雙向綁定就是通過使用Object.defineProperty去定義數據屬性的getter與setter方法來實現的,比如下面有一個對象
let obj = {
name: '子君',
officialAccounts: '前端有的玩'
}
我希望這個對象里面的用戶名是不能被修改的,用Object.defineProperty該如何定義呢?
Object.defineProperty(obj,'name', {
// 設置writable 是 false, 這個屬性將不能被修改
writable: false
})
// 修改obj.name
obj.name = "君子"
// 打印依然是子君
console.log(obj.name)
通過Object.defineProperty可以去定義或者修改對象屬性的屬性描述符,但是因為數據屬性與訪問器屬性是互斥的,所以一次只能修改其中的一類,這一點需要注意。
定義一個防抖裝飾器
裝飾器本質上依然是一個函數,不過這個函數的參數是固定的,如下是防抖裝飾器的代碼
/**
*@param wait 延遲時長
*/
function debounce(wait) {
return function(target, name, descriptor) {
descriptor.value = debounce(descriptor.value, wait)
}
}
// 使用方式
class MyClass {
@debounce(100)
follow() {
console.log('我是子君,我的公眾號是 【前端有的玩】,關注有驚喜哦')
}
}
我們逐行去分析一下代碼
首先我們定義了一個 debounce函數,同時有一個參數wait,這個函數對應的就是在下面調用裝飾器時使用的@debounce(100)
debounce函數返回了一個新的函數,這個函數即裝飾器的核心,這個函數有三個參數,下面逐一分析
target: 這個類屬性函數是在誰上面掛載的,如上例對應的是MyClass類
name: 這個類屬性函數的名稱,對應上面的follow
descriptor: 這個就是我們前面說的屬性描述符,通過直接descriptor上面的屬性,即可實現屬性只讀,數據重寫等功能
然后第三行 descriptor.value = debounce(descriptor.value, wait), 前面我們已經了解到,屬性描述符上面的value對應的是這個屬性的值,所以我們通過重寫這個屬性,將其用debounce函數包裝起來,這樣在函數調用follow時實際調用的是包裝后的函數
通過上面的三步,我們就實現了類屬性上面可使用的裝飾器,同時將其應用到了類屬性上面
在class上使用裝飾器
裝飾器不僅可以應用到類屬性上面,還可以直接應用到類上面,比如我希望可以實現一個類似Vue混入那樣的功能,給一個類混入一些方法屬性,應該如何去做呢?
// 這個是要混入的對象
const methods = {
logger() {
console.log('記錄日志')
}
}
// 這個是一個登陸登出類
class Login{
login() {}
logout() {}
}
如何將上面的methods混入到Login中,首先我們先實現一個類裝飾器
function mixins(obj) {
return function (target) {
Object.assign(target.prototype, obj)
}
}
// 然后通過裝飾器混入
@mixins(methods)
class Login{
login() {}
logout() {}
}
這樣就實現了類裝飾器。對于類裝飾器,只有一個參數,即target,對應的就是這個類本身。
了解完裝飾器,我們接下來看一下如何在Vue中使用裝飾器。
在Vue中使用裝飾器
使用ts開發Vue的同學一定對vue-property-decorator不會感到陌生,這個插件提供了許多裝飾器,方便大家開發的時候使用,當然本文的中點不是這個插件。其實如果我們的項目沒有使用ts,也是可以使用裝飾器的,怎么用呢?
配置基礎環境
除了一些老的項目,我們現在一般新建Vue項目的時候,都會選擇使用腳手架vue-cli3/4來新建,這時候新建的項目已經默認支持了裝飾器,不需要再配置太多額外的東西,如果你的項目使用了eslint,那么需要給eslint配置以下內容。
parserOptions: {
ecmaFeatures:{
// 支持裝飾器
legacyDecorators: true
}
}
使用裝飾器
雖然Vue的組件,我們一般書寫的時候export出去的是一個對象,但是這個并不影響我們直接在組件中使用裝飾器,比如就拿上例中的log舉例。
function log() {
/**
* @param target 對應 methods 這個對象
* @param name 對應屬性方法的名稱
* @param descriptor 對應屬性方法的修飾符
*/
return function(target, name, descriptor) {
console.log(target, name, descriptor)
const fn = descriptor.value
descriptor.value = function(...rest) {
console.log(`這是調用方法【${name}】前打印的日志`)
fn.call(this, ...rest)
console.log(`這是調用方法【${name}】后打印的日志`)
}
}
}
export default {
created() {
this.getData()
},
methods: {
@log()
getData() {
console.log('獲取數據')
}
}
}
看了上面的代碼,是不是發現在Vue中使用裝飾器還是很簡單的,和在class的屬性上面使用的方式一模一樣,但有一點需要注意,在methods里面的方法上面使用裝飾器,這時候裝飾器的target對應的是methods。
除了在methods上面可以使用裝飾器之外,你也可以在生命周期鉤子函數上面使用裝飾器,這時候target對應的是整個組件對象。
一些常用的裝飾器
下面小編羅列了幾個小編在項目中常用的幾個裝飾器,方便大家使用
1. 函數節流與防抖
函數節流與防抖應用場景是比較廣的,一般使用時候會通過throttle或debounce方法對要調用的函數進行包裝,現在就可以使用上文說的內容將這兩個函數封裝成裝飾器, 防抖節流使用的是lodash提供的方法,大家也可以自行實現節流防抖函數哦
import { throttle, debounce } from 'lodash'
/**
* 函數節流裝飾器
* @param {number} wait 節流的毫秒
* @param {Object} options 節流選項對象
* [options.leading=true] (boolean): 指定調用在節流開始前。
* [options.trailing=true] (boolean): 指定調用在節流結束后。
*/
export const throttle = function(wait, options = {}) {
return function(target, name, descriptor) {
descriptor.value = throttle(descriptor.value, wait, options)
}
}
/**
* 函數防抖裝飾器
* @param {number} wait 需要延遲的毫秒數。
* @param {Object} options 選項對象
* [options.leading=false] (boolean): 指定在延遲開始前調用。
* [options.maxWait] (number): 設置 func 允許被延遲的最大值。
* [options.trailing=true] (boolean): 指定在延遲結束后調用。
*/
export const debounce = function(wait, options = {}) {
return function(target, name, descriptor) {
descriptor.value = debounce(descriptor.value, wait, options)
}
}
封裝完之后,在組件中使用
import {debounce} from '@/decorator'
export default {
methods:{
@debounce(100)
resize(){}
}
}
2. loading
在加載數據的時候,為了個用戶一個友好的提示,同時防止用戶繼續操作,一般會在請求前顯示一個loading,然后在請求結束之后關掉loading,一般寫法如下
export default {
methods:{
async getData() {
const loading = Toast.loading()
try{
const data = await loadData()
// 其他操作
}catch(error){
// 異常處理
Toast.fail('加載失敗');
}finally{
loading.clear()
}
}
}
}
我們可以把上面的loading的邏輯使用裝飾器重新封裝,如下代碼
import { Toast } from 'vant'
/**
* loading 裝飾器
* @param {*} message 提示信息
* @param {function} errorFn 異常處理邏輯
*/
export const loading = function(message = '加載中...', errorFn = function() {}) {
return function(target, name, descriptor) {
const fn = descriptor.value
descriptor.value = async function(...rest) {
const loading = Toast.loading({
message: message,
forbidClick: true
})
try {
return await fn.call(this, ...rest)
} catch (error) {
// 在調用失敗,且用戶自定義失敗的回調函數時,則執行
errorFn && errorFn.call(this, error, ...rest)
console.error(error)
} finally {
loading.clear()
}
}
}
}
然后改造上面的組件代碼
export default {
methods:{
@loading('加載中')
async getData() {
try{
const data = await loadData()
// 其他操作
}catch(error){
// 異常處理
Toast.fail('加載失敗');
}
}
}
}
3. 確認框
當你點擊刪除按鈕的時候,一般都需要彈出一個提示框讓用戶確認是否刪除,這時候常規寫法可能是這樣的
import { Dialog } from 'vant'
export default {
methods: {
deleteData() {
Dialog.confirm({
title: '提示',
message: '確定要刪除數據,此操作不可回退。'
}).then(() => {
console.log('在這里做刪除操作')
})
}
}
}
我們可以把上面確認的過程提出來做成裝飾器,如下代碼
import { Dialog } from 'vant'
/**
* 確認提示框裝飾器
* @param {*} message 提示信息
* @param {*} title 標題
* @param {*} cancelFn 取消回調函數
*/
export function confirm(
message = '確定要刪除數據,此操作不可回退。',
title = '提示',
cancelFn = function() {}
) {
return function(target, name, descriptor) {
const originFn = descriptor.value
descriptor.value = async function(...rest) {
try {
await Dialog.confirm({
message,
title: title
})
originFn.apply(this, rest)
} catch (error) {
cancelFn && cancelFn(error)
}
}
}
}
然后再使用確認框的時候,就可以這樣使用了
export default {
methods: {
// 可以不傳參,使用默認參數
@confirm()
deleteData() {
console.log('在這里做刪除操作')
}
}
}
是不是瞬間簡單多了,當然還可以繼續封裝很多很多的裝飾器,因為文章內容有限,暫時提供這三個。
裝飾器組合使用
在上面我們將類屬性上面使用裝飾器的時候,說道裝飾器可以組合使用,在Vue組件上面使用也是一樣的,比如我們希望在確認刪除之后,調用接口時候出現loading,就可以這樣寫(一定要注意順序)
export default {
methods: {
@confirm()
@loading()
async deleteData() {
await delete()
}
}
}
本節定義的裝飾器,均已應用到這個項目中 https://github.com/snowzijun/vue-vant-base, 這是一個基于Vant開發的開箱即用移動端框架,你只需要fork下來,無需做任何配置就可以直接進行業務開發,歡迎使用,喜歡麻煩給一個star。
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
藍藍設計的小編 http://www.syprn.cn