千呼萬喚始出來,猶戴口罩半遮面
要說上周什么消息最激動人心,那絕對是全國7月20日低風險地區電影院重開無疑了
消息一出,蟄伏數月的電影愛好者們,紛紛傾巢出動在央媽的評論區里為電影提前打Call。
各種網絡段子也是應聲齊飛:什么待業電影院員工急售餐車搶復工;上座率不超30%,情侶們也得分開坐
想必各位鴨脖聽聞也是激動難耐特別是海報設計師們,終于不用因為沒活兒繼續挨餓了
趁此機會,先來看看電影海報,一來可解相思之苦,順便排一排雷,還能邊挑邊學設計技巧,三全其美,豈不快哉:
1. 誤殺
重映時間—7月20日
近年來難得一見的國產劇情好電影,單從海報上就可見一斑。
「看1000部電影」不能助你飛黃騰達,卻能讓你將世人的眼睛玩弄于股掌,既然生活是一部電影,那就沒有什么是不能人為去剪輯的。
表面上束手就擒的一家人,實則齊心協力,暗度陳倉。
如果你認為孩子畫的案發現場,將成為如山鐵證,那么恭喜你,人都還沒進影院,就已經陷入了導演的敘事詭計。
2. 第一次的離別
上映時間—7月20日
發生在新疆男孩與母親間的溫情故事,母親患病無法言語,更時常離家出走,兩小無猜的男孩女孩,毅然穿越漫漫黃沙,踏上尋母的道路。
沙漠中,只要三個人影在孤獨地行走路的盡頭,究竟是與人別離,還是要跟童年別離,或許,二者都是。
3. 璀璨薪火
上映時間—7月20日
作為非物質文化遺產紀錄片的海報一只飽經風霜的粗糙的手,談不上精妙創意,甚至頗有些質樸。
但別忘了,正是這一雙雙沉穩的手,日復一日,年復一年守護著國人傲立世界的文化的驕傲。
4. 妙先生
上映時間—7月31日
年度話題大作《大護法》的姊妹篇有關「善良」的深刻討論,如果每次拯救惡人,都要犧牲好人,那這種所謂的拯救,究竟還值不值。
溫馨提示,內有大漢「聚眾賞菊」是成年人畫給成年人看的動畫片。
5. 呆瓜兄弟
上映時間—7月31日
從1976年開播的第一集就讓觀眾捧腹大笑的木偶短片。
40年后重聚的不光是這兩只呆瓜更是熒幕前的觀眾與自己的童年。
1. 我想靜靜
上映時間—8月07日
號稱「國內首部動物喜劇電影」海報卻疑似「寵物店」素材打底。
以上動物皆不會出現在電影中怕不光是「首部寵物喜劇」更是「首部魔幻現實主義作品」
2. 蕎麥瘋長
上映時間—8月25日
神似一年一度感動中國的構圖展現著上世紀90年代,三個相互交織串聯的青年人生。
在人們熱衷討論00后、05后的當下導演將鏡頭對準70、80,在建的東方明珠,既是時代的挽歌也是對一代青年人美好未來的贊美。
3. 我在時間盡頭等你
上映時間—8月25日
偶然間獲得的超能力讓男主能夠回到過去,挽救愛情卻被命運捉弄,始終都不得圓滿
與《時空戀旅人》同樣的科幻題材海報當中,也有十分相似的一場雨,希望如同《流浪地球》,國人能再次拍出不輸經典的高水準。
4. 小婦人
上映時間—8月待定
女性可以柔弱,也可以擁有高傲的頭顱南北戰爭中的四姐妹,在清苦生活中活出了不一樣的堅強人生。
5. 急先鋒
上映時間—8月待定
角落里熊熊燃燒的美國核動力航母身后高聳入云的迪拜塔,沒有一處不在透露著這是部大制作。
從沙漠到瀑布,劇情搭不搭且不說至少光是海報就搭了不少真金白銀。
上映時間—8月待定
一心想揭露社會陰暗丑惡的新聞記者處處與人為善的老好人,矛盾的二者相遇,會是場何樣的鬧劇。
上一秒促膝長談,下一秒皮鞋橫飛「鄰里間的美好」或許本身就是偽命題。
6. 許愿神龍
上映時間—8月待定
上海少年誤打誤撞喚醒沉睡神龍卻發自己與龍有著上千年的代溝,西式畫風,中式溫情,一人一龍的冒險故事,值得一看。
7. 無名狂
上映時間—9月25日
一部誕生于摩點眾籌的眾籌電影片名叫《無名狂》,海報卻寫滿了贊助的網友的名字。
圍繞萬歷年間兩大刺客門派所展開的一場場腥風血雨,平靜海報之下,山呼海嘯,風雨欲來。
除此之外,還有不少電影尚未排期,全年隨時可能上映。其中自然也不缺乏優秀的海報創意,比如從路人視角,見證抗戰歷史的《八佰》。
克味十足,容易聯想到哈利波特系列的《刺殺小說家》
單靠海報配色就能讓人陷入迷惑的《抵達之謎》
頗有08年阿迪達斯海報味道的《奪冠》
用風卷云涌展現中式諸神之戰的《封神三部曲》
居然還能拍出第二部的《爵跡2》
正看是海浪,倒看是山巒的《一直游到海水變藍》
近看是懸崖,遠看是槍口的《懸崖之上》
六小齡童老師參與動捕制作今年下半年…可能會上映的《真假美猴王》
希望別播完片頭就播staff名單的《一秒鐘》
能把牛頓從棺材里嚇活過來的《神秘訪客》
進退兩男、男上加男、滿身大漢的《唐人街探案3》
生死一線間淡定到面帶微笑的《緊急救援》
以及萬眾期待的封神宇宙大片《姜子牙》
好了,以上就是2020年將要上映以及可能上映的電影的海報大合集??赐炅诉@些精彩的海報焦急的等待之情是否緩解了一些?
倒也正應了那句老話,只要熬過低谷,后面都是更好的一天。
文章來源:優設 作者:你丫才美工
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
我們應該學習 webpack 嗎 ?
如今,CLI工具(如create-react-app或Vue -cli)已經為我們抽象了大部分配置,并提供了合理的默認設置。
即使那樣,了解幕后工作原理還是有好處的,因為我們遲早需要對默認值進行一些調整。
在本文中中,我們會知道 webpack可以做什么,以及如何配置它以滿足我們的日常需求。
什么是 webpack?
作為前端開發人員,我們應該熟悉 module 概念。 你可能聽說過 AMD模塊,UMD,Common JS還有ES模塊。
webpack是一個模塊綁定器,它對模塊有一個更廣泛的定義,對于webpack來說,模塊是:
Common JS modules
AMD modules
CSS import
Images url
ES modules
webpack 還可以從這些模塊中獲取依賴關系。
webpack 的最終目標是將所有這些不同的源和模塊類型統一起來,從而將所有內容導入JavaScript代碼,并最生成可以運行的代碼。
entry
Webpack的 entry(入口點)是收集前端項目的所有依賴項的起點。 實際上,這是一個簡單的 JavaScript 文件。
這些依賴關系形成一個依賴關系圖。
Webpack 的默認入口點(從版本4開始)是src/index.js,它是可配置的。 webpack 可以有多個入口點。
Output
output是生成的JavaScript和靜態文件的地方。
Loaders
Loaders 是第三方擴展程序,可幫助webpack處理各種文件擴展名。 例如,CSS,圖像或txt文件。
Loaders的目標是在模塊中轉換文件(JavaScript以外的文件)。 文件成為模塊后,webpack可以將其用作項目中的依賴項。
Plugins
插件是第三方擴展,可以更改webpack的工作方式。 例如,有一些用于提取HTML,CSS或設置環境變量的插件。
Mode
webpack 有兩種操作模式:開發(development)和生產(production)。 它們之間的主要區別是生產模式自動生成一些優化后的代碼。
Code splitting
代碼拆分或延遲加載是一種避免生成較大包的優化技術。
通過代碼拆分,開發人員可以決定僅在響應某些用戶交互時加載整個JavaScript塊,比如單擊或路由更改(或其他條件)。
被拆分的一段代碼稱為 chunk。
Webpack入門
開始使用webpack時,先創建一個新文件夾,然后進入該文件中,初始化一個NPM項目,如下所示:
mkdir webpack-tutorial && cd $_
npm init -y
接著安裝 webpack,webpack-cli和 webpack-dev-server:
npm i webpack webpack-cli webpack-dev-server --save-dev
要運行 webpack,只需要在 package.json 配置如下命令即可:
"scripts": {
"dev": "webpack --mode development"
},
通過這個腳本,我們指導webpack在開發模式下工作,方便在本地工作。
Webpack 的第一步
在開發模式下運行 webpack:
npm run dev
運行完后會看到如下錯誤:
ERROR in Entry module not found: Error: Can't resolve './src'
webpack 在這里尋找默認入口點src/index.js,所以我們需要手動創建一下,并輸入一些內容:
mkdir src
echo 'console.log("Hello webpack!")' > src/index.js
現在再次運行npm run dev,錯誤就沒有了。 運行的結果生成了一個名為dist/的新文件夾,其中包含一個名為main.js的 JS 文件:
dist
└── main.js
這是我們的第一個webpack包,也稱為output。
配置 Webpack
對于簡單的任務,webpack無需配置即可工作,但是很快我們就會遇到問題,一些文件如果沒有指定的 loader 是沒法打包的。所以,我們需要對 webpack進行配置,對于 webpack 的配置是在 webpack.config.js 進行的,所以我們需要創建該文件:
touch webpack.config.js
Webpack 用 JavaScript 編寫,并在無頭 JS 環境(例如Node.js)上運行。 在此文件中,至少需要一個module.exports,這是的 Common JS 導出方式:
module.exports = {
//
};
在webpack.config.js中,我們可以通過添加或修改來改變webpack的行為方式
entry point
output
loaders
plugins
code splitting
例如,要更改入口路徑,我們可以這樣做
const path = require("path");
module.exports = {
entry: { index: path.resolve(__dirname, "source", "index.js") }
};
現在,webpack 將在source/index.js中查找要加載的第一個文件。 要更改包的輸出路徑,我們可以這樣做:
const path = require("path");
module.exports = {
output: {
path: path.resolve(__dirname, "build")
}
}
這樣,webpack將把最終生成包放在build中,而不是dist.(為了簡單起見,在本文中,我們使用默認配置)。
打包 HTML
沒有HTML頁面的Web應用程序幾乎沒有用。 要在webpack中使用 HTML,我們需要安裝一個插件html-webpack-plugin:
npm i html-webpack-plugin --save-dev
一旦插件安裝好,我們就可以對其進行配置:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
};
這里的意思是讓 webpack,從 src/index.html 加載 HTML 模板。
html-webpack-plugin的最終目標有兩個:
加載 html 文件
它將bundle注入到同一個文件中
接著,我們需要在 src/index.html 中創建一個簡單的 HTML 文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack tutorial</title>
</head>
<body>
</body>
</html>
稍后,我們會運行這個程序。
webpack development server
在本文第一部分中,我們安裝了webpack-dev-server。如果你忘記安裝了,現在可以運行下面命令安裝一下:
npm i webpack-dev-server --save-dev
webpack-dev-server 可以讓開發更方便,不需要改動了文件就去手動刷新文件。 配置完成后,我們可以啟動本地服務器來提供文件。
要配置webpack-dev-server,請打開package.json并添加一個 “start” 命令:
"scripts": {
"dev": "webpack --mode development",
"start": "webpack-dev-server --mode development --open",
},
有了 start 命令,我們來跑一下:
npm start
運行后,默認瀏覽器應打開。 在瀏覽器的控制臺中,還應該看到一個 script 標簽,引入的是我們的 main.js。
clipboard.png
使用 webpack loader
Loader是第三方擴展程序,可幫助webpack處理各種文件擴展名。 例如,有用于 CSS,圖像或 txt 文件的加載程序。
下面是一些 loader 配置介紹:
module.exports = {
module: {
rules: [
{
test: /\.filename$/,
use: ["loader-b", "loader-a"]
}
]
},
//
};
相關配置以module 關鍵字開始。 在module內,我們在rules內配置每個加載程序組或單個加載程序。
對于我們想要作為模塊處理的每個文件,我們用test和use配置一個對象
{
test: /\.filename$/,
use: ["loader-b", "loader-a"]
}
test 告訴 webpack “嘿,將此文件名視為一個模塊”。 use 定義將哪些 loaders 應用于些打包的文件。
打包 CSS
要 在webpack 中打包CSS,我們需要至少安裝兩個 loader。Loader 對于幫助 webpack 了解如何處理.css文件是必不可少的。
要在 webpack 中測試 CSS,我們需要在 src 下創建一個style.css文件:
h1 {
color: orange;
}
另外在 src/index.html 添加 h1 標簽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack tutorial</title>
</head>
<body>
<h1>Hello webpack!</h1>
</body>
</html>
最后,在src/index.js 中加載 CSS:
在測試之前,我們需要安裝兩個 loader:
css-loader: 解析 css 代碼中的 url、@import語法像import和require一樣去處理css里面引入的模塊
style-loader:幫我們直接將css-loader解析后的內容掛載到html頁面當中
安裝 loader:
npm i css-loader style-loader --save-dev
然后在webpack.config.js中配置它們
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
};
現在,如果你運行npm start,會看到樣式表加載在HTML的頭部:
clipboard.png
一旦CSS Loader 就位,我們還可以使用MiniCssExtractPlugin提取CSS文件
Webpack Loader 順序很重要!
在webpack中,Loader 在配置中出現的順序非常重要。以下配置無效:
//
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ["css-loader", "style-loader"]
}
]
},
//
};
此處,“style-loader”出現在 “css-loader” 之前。 但是style-loader用于在頁面中注入樣式,而不是用于加載實際的CSS文件。
相反,以下配置有效:
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
//
};
webpack loaders 是從右到左執行的。
打包 sass
要在 webpack 中測試sass,同樣,我們需要在 src 目錄下創建一個 style.scss 文件:
@import url("https://fonts.googleapis.com/css?family=Karla:weight@400;700&display=swap");
$font: "Karla", sans-serif;
$primary-color: #3e6f9e;
body {
font-family: $font;
color: $primary-color;
}
另外,在src/index.html中添加一些 Dom 元素:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Webpack tutorial</title>
</head>
<body>
<h1>Hello webpack!</h1>
<p>Hello sass!</p>
</body>
</html>
最后,將 sass 文件加載到src/index.js中:
import "./style.scss";
console.log("Hello webpack!");
在測試之前,我們需要安裝幾個 loader:
sass-loader:加載 SASS / SCSS 文件并將其編譯為 CSS
css-loader: 解析 css 代碼中的 url、@import語法像import和require一樣去處理css里面引入的模塊
style-loader:幫我們直接將css-loader解析后的內容掛載到html頁面當中
安裝 loader:
npm i css-loader style-loader sass-loader sass --save-dev
然后在webpack.config.js中配置它們:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
};
注意loader的出現順序:首先是sass-loader,然后是css-loader,最后是style-loader。
現在,運行npm start,你應該會在HTML的頭部看到加載的樣式表:
clipboard.png
打包現代 JavaScrip
webpack 本身并不知道如何轉換JavaScript代碼。 該任務已外包給babel的第三方 loader,特別是babel-loader。
babel是一個JavaScript編譯器和“編譯器”。 babel 可以將現代JS(es6, es7...)轉換為可以在(幾乎)任何瀏覽器中運行的兼容代碼。
同樣,要使用它,我們需要安裝一些 Loader:
babel-core :把 js 代碼分析成 ast ,方便各個插件分析語法進行相應的處理
babel-preset-env:將現代 JS 編譯為ES5
babel-loader :用于 webpack
引入依賴關系
npm i @babel/core babel-loader @babel/preset-env --save-dev
接著,創建一個新文件babel.config.json配置babel,內容如下:
{
"presets": [
"@babel/preset-env"
]
}
最后在配置一下 webpack :
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"]
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html")
})
]
};
要測試轉換,可以在 src/index.js中編寫一些現代語法:
import "./style.scss";
console.log("Hello webpack!");
const fancyFunc = () => {
return [1, 2];
};
const [a, b] = fancyFunc();
現在運行npm run dev來查看dist中轉換后的代碼。 打開 dist/main.js并搜索“fancyFunc”:
\n\nvar fancyFunc = function fancyFunc() {\n return [1, 2];\n};\n\nvar _fancyFunc = fancyFunc(),\n _fancyFunc2 = _slicedToArray(_fancyFunc, 2),\n a = _fancyFunc2[0],\n b = _fancyFunc2[1];\n\n//# sourceURL=webpack:///./src/index.js?"
沒有babel,代碼將不會被轉譯:
\n\nconsole.log(\"Hello webpack!\");\n\nconst fancyFunc = () => {\n return [1, 2];\n};\n\nconst [a, b] = fancyFunc();\n\n\n//# sourceURL=webpack:///./src/index.js?");
注意:即使沒有babel,webpack也可以正常工作。 僅在執行 ES5 代碼時才需要進行代碼轉換過程。
在 Webpack 中使用 JS 的模塊
webpack 將整個文件視為模塊。 但是,請不要忘記它的主要目的:加載ES模塊。
ECMAScript模塊(簡稱ES模塊)是一種JavaScript代碼重用的機制,于2015年推出,一經推出就受到前端開發者的喜愛。在2015之年,JavaScript 還沒有一個代碼重用的標準機制。多年來,人們對這方面的規范進行了很多嘗試,導致現在有多種模塊化的方式。
你可能聽說過AMD模塊,UMD,或CommonJS,這些沒有孰優孰劣。最后,在ECMAScript 2015中,ES 模塊出現了。
我們現在有了一個“正式的”模塊系統。
要在 webpack 使用 ES module ,首先創建 src/common/usersAPI.js 文件:
const ENDPOINT = "https://jsonplaceholder.typicode.com/users/";
export function getUsers() {
return fetch(ENDPOINT)
.then(response => {
if (!response.ok) throw Error(response.statusText);
return response.json();
})
.then(json => json);
}
在 src/index.js中,引入上面的模塊:
import { getUsers } from "./common/usersAPI";
import "./style.scss";
console.log("Hello webpack!");
getUsers().then(json => console.log(json));
生產方式
如前所述,webpack有兩種操作模式:開發(development )和(production)。 到目前為止,我們僅在開發模式下工作。
在開發模式中,為了便于代碼調試方便我們快速定位錯誤,不會壓縮混淆源代碼。相反,在生產模式下,webpac k進行了許多優化:
使用 TerserWebpackPlugin 進行縮小以減小 bundle 的大小
使用ModuleConcatenationPlugin提升作用域
在生產模式下配 置webpack,請打開 package.json 并添加一個“ build” 命令:
現在運行 npm run build,webpack 會生成一個壓縮的包。
Code splitting
代碼拆分(Code splitting)是指針對以下方面的優化技術:
避免出現一個很大的 bundle
避免重復的依賴關系
webpack 社區考慮到應用程序的初始 bundle 的最大大小有一個限制:200KB。
在 webpack 中有三種激活 code splitting 的主要方法:
有多個入口點
使用 optimization.splitChunks 選項
動態導入
第一種基于多個入口點的技術適用于較小的項目,但是從長遠來看它是不可擴展的。這里我們只關注第二和第三種方式。
Code splitting 與 optimization.splitChunks
考慮一個使用Moment.js 的 JS 應用程序,Moment.js是流行的時間和日期JS庫。
在項目文件夾中安裝該庫:
npm i moment
現在清除src/index.js的內容,并引入 moment 庫:
import moment from "moment";
運行 npm run build 并查看控制的輸出內容:
main.js 350 KiB 0 [emitted] [big] main
整個 moment 庫都綁定到了 main.js 中這樣是不好的。借助optimization.splitChunks,我們可以從主包中移出moment.js。
要使用它,需要在 webpack.config.js 添加 optimization 選項:
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");
module.exports = {
module: {
// ...
},
optimization: {
splitChunks: { chunks: "all" }
},
// ...
};
運行npm run build 并查看運行結果:
main.js 5.05 KiB 0 [emitted] main
vendors~main.js 346 KiB 1 [emitted] [big] vendors~main
現在,我們有了一個帶有moment.js 的vendors?main.js,而主入口點的大小更合理。
注意:即使進行代碼拆分,moment.js仍然是一個體積較大的庫。 有更好的選擇,如使用luxon或date-fns。
Code splitting 與 動態導入
Code splitting的一種更強大的技術使用動態導入來有條件地加載代碼。 在ECMAScript 2020中提供此功能之前,webpack 提供了動態導入。
這種方法在 Vue 和 React 之類的現代前端庫中得到了廣泛使用(React有其自己的方式,但是概念是相同的)。
Code splitting 可用于:
模塊級別
路由級別
例如,你可以有條件地加載一些 JavaScript 模塊,以響應用戶的交互(例如單擊或鼠標移動)。 或者,可以在響應路由更改時加載代碼的相關部分。
要使用動態導入,我們先清除src/index.html,并寫入下面的內容:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dynamic imports</title>
</head>
<body>
<button id="btn">Load!</button>
</body>
</html>
在 src/common/usersAPI.js中:
const ENDPOINT = "https://jsonplaceholder.typicode.com/users/";
export function getUsers() {
return fetch(ENDPOINT)
.then(response => {
if (!response.ok) throw Error(response.statusText);
return response.json();
})
.then(json => json);
}
在 src/index.js 中
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
//
});
如果運行npm run start查看并單擊界面中的按鈕,什么也不會發生。
現在想象一下,我們想在某人單擊按鈕后加載用戶列表。 “原生”的方法可以使用靜態導入從src/common /usersAPI.js加載函數:
import { getUsers } from "./common/usersAPI";
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
getUsers().then(json => console.log(json));
});
問題在于ES模塊是靜態的,這意味著我們無法在運行時更改導入的內容。
通過動態導入,我們可以選擇何時加載代碼
const getUserModule = () => import("./common/usersAPI");
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
getUserModule().then(({ getUsers }) => {
getUsers().then(json => console.log(json));
});
});
這里我們創建一個函數來動態加載模塊
const getUserModule = () => import("./common/usersAPI");
現在,當你第一次使用npm run start加載頁面時,會看到控制臺中已加載 js 包:
clipboard.png
現在,僅在單擊按鈕時才加載/common/usersAPI:
clipboard.png
對應的 chunk 是 0.js
通過在導入路徑前面加上魔法注釋/ * webpackChunkName:“ name_here” * /,可以更改塊名稱:
const getUserModule = () =>
import(/* webpackChunkName: "usersAPI" */ "./common/usersAPI");
const btn = document.getElementById("btn");
btn.addEventListener("click", () => {
getUserModule().then(({ getUsers }) => {
getUsers().then(json => console.log(json));
});
});
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
準備工作
//借助插件
npm install babel-plugin-import --save-dev
// .babelrc
{
"plugins": [["import", {
"libraryName": "view-design",
"libraryDirectory": "src/components"
}]]
}
在main.js中引入
import "view-design/dist/styles/iview.css";
import { Button, Table } from "view-design";
const viewDesign = {
Button: Button,
Table: Table
};
Object.keys(viewDesign).forEach(element => {
Vue.component(element, viewDesign[element]);
});
先用google瀏覽器打開正常,以上操作猛如虎,IE瀏覽器打開250,好了不廢話,下面是解決方案
解決方案
//vue.config.js中配置
chainWebpack: config => {
//解決iview 按需引入babel轉換問題
config.module
.rule("view-design") // 我目前用的是新版本的iview ,舊版本的iview,用iview代替view-design
.test(/view-design.src.*?js$/)
.use("babel")
.loader("babel-loader")
.end();
}
問題原因
為什么會有如上問題呢? 這個就和babel轉換問題有關了,按需引入時,那些組件里js文件未進行babel轉換或轉換不徹底就被引入了,ie11對es6+的語法支持是很差的,所以以上方法就是讓引入文件前就對view-design的src下的所有js文件進行babel轉換,舉一反三,當按需引入第三方框架時出現這個問題,都可用這方法解決了,只要把規則和正則中view-design進行替換。
延伸擴展
//全局引入
import ViewUI from "view-design";
Vue.use(ViewUI);
import "view-design/dist/styles/iview.css";
tips:在全局引入時,一定要記住不要在.babelrc文件里配置按需導入,會導致沖突
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
用戶隱私安全在產品設計中是很重要的一個環節,本文從用戶體驗角度切入,從匿名模式、減少永久性和減少公開性三個方面展開分析。
我們先看?組來??優的2019年6?的調研數據:70%的美國?認為,與5年前相?個?信息變得更不安全。尤其是?學歷?收?群體。由此可??戶對個?信息數據的隱私擔憂?以往更甚。
?戶隱私安全很重要,涉及的范圍和?度也很多。本次的分析從?戶體驗?度切?,涉及如下三個??:
下圖是Google系App(Google AppChromeYouTubeandGoogle Map)匿名模式切換,從交互體驗上來說有如下?個特點:
匿名模式不是最近才流?的功能,最早提供隱匿模式的是蘋果safari瀏覽器,早在 2005年就?持了匿名模式。Chrome瀏覽器在2008年就開始?持此模式。雖然由來已久,為什么到了2020年,匿名模式依然是國外互聯???趨勢呢?
我們看?組數據:
這是來?DuckDuckGo 2019年9?的調研(DuckDuckGo是美國的?款不記錄?戶?為保護?戶隱私的搜索引擎)。樣本來?美國、英國、德國和澳?利亞的成年??戶,共計3,411?的調研得出。各國?戶對使?搜索引擎的個?隱私安全?常在意(是否搜集個?的數據和記錄搜索?為)。
2020年5?DuckDuckGo?均搜索次數為6200萬。對?看2019年11?底?均搜索次數4900萬,2018年10?是2900萬。
最近?年的持續活躍度?幅增?證明了不記錄個?隱私的搜素引擎越來越受到?戶的?睞。
國內,頭條、UC瀏覽器在搜索框輸?狀態也提供了「?痕瀏覽」??。
不僅是搜索引擎領域,保護?戶隱私也成為Facebook最重要的戰略?向之?。Facebook CEO Mark Zuckerberg在2019年 F8開發者?會上喊出「THE FUTURE IS PRIVATE」。2019年3?Mark Zuckerberg發?,主題就是《聚焦于保護隱私的社交?絡》。
我們先看國外社交媒體Stories(?故事)產品形態的流?。
?們總是對于所分享的內容永遠記錄在?上感到擔憂。Stories 24?時消失緩解了?們的隱私顧慮,這讓?戶更安?地?然分享。
Stories由Snapchat?創,由 Facebook發揚光?。早在2019年4?,Facebook+Messenger Stories, Instagram Stories?活?戶數就突破5億。 2020年2-3?LinkedIn,Twitter也先后宣布將上線類似功能。
來??優的調研報告:41%的美國?經歷過?絡騷擾,最常?的就是在社交媒體上。23%的?戶最近經歷的?絡騷擾來?評論區的評論內容。27%的?戶經歷?絡騷擾后決定不再發布任何內容。
我們以限定評論互動的公開性為例:
2020年5?Twitter上線了新的評論功能,可以限定誰可以回復帖?的功能,提供了三種選項:誰都可以評論,只有被關注者可以評論,只有被提及者可以評論三種公開度的限定。
Instagram也在測試「評論限制」新功能,批量屏蔽/限制評論。?前已經上線的?個例?:?戶(評論發布者)如果發布的評論含有攻擊性敏感詞,發布前伴有提示,提醒評論含有攻擊性敏感詞是否真的要發布。
注重隱私提供僅好友可?/僅??可?/僅作者可?/等多重維度的隱私設定有助于?戶更安?地參與互動。
另外?個例?是付費頻道會員:付費頻道會員-限定頻道的公開性讓內容創作者減輕隱私顧慮不僅能獲得?告收?,也能得到來?會員、會費的收?,形成「忠實粉絲」社區,有助于內容?態的社區化建設。
我們主要看YouTube的頻道會員案例:
YouTube有兩種會員模式。?種是YouTube整個平臺的付費會員,去?告,看原創美劇影視,消費?樂,可下載內容的模式。第?種模式是Youtuber個?頻道付費會員,吸引忠實粉絲加?。我想說的就是第?種。
為什么?V?紅有意愿開通頻道會員?
除了獲得忠實粉絲收?變現的商業價值以及付費頻道會員可以為忠實粉絲提供各種專屬功能,背后也和?紅?V對個?隱私顧慮有關。
?紅?V在完全公開的社交?絡上需要始終保持?夠克制謹慎,避免引起爭議。但在忠實粉絲付費頻道專屬會員群中,?紅?V會減輕隱私顧慮,更加回歸?我。
?如在頻道會員中發布更多與個??活相關的內容,表達更多不便在完全公開的社交?絡中的想法和感受等,因為忠實粉絲通常更具包容度,更不容易引起爭議。
YouTube頻道會員費?可以從三種會費(按?)區間選擇,?持多選:
頻道會員功能在2018年開始測試,?向粉絲數過10萬的YouTuber開放。
以上綜述,我們可以說:
1. 匿名模式:
雖然匿名模式由來已久,但仍然是當前的??基本?戶體驗設計趨勢,尤其是匿名模式的切換便捷性?常重要。
2. 減少永久性:
Stories?故事24?時消失緩解了?們的隱私顧慮,這讓?戶更安?地?然分享,已經成為國外社交媒體平臺的必備功能,Facebook, Instagram平臺的最主要、最具影響?的功能之?。
3. 減少公開性:
?戶總是對在社交媒體平臺發表評論有所顧忌,限定評論的公開性能夠有助于促進?戶發帖表達,其他?戶也可以更安?地參與互動。
付費頻道會員可以限定頻道的公開性,讓內容創作者減輕隱私顧慮不僅能獲得?告收?,也能得到來?會員會費的收?,形成「忠實粉絲」社區,有助于內容?態的社區化建設。
從UE?度,我們可以為頻道會員提供專屬身份設計例如專屬徽章,專屬表情等。
THE FUTURE IS PRIVATE, 注重?戶隱私的體驗設計越來越重要!
文章來源:優設 作者:
百度MEUX
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
最近在項目中遇到這樣一個問題
當頁面加載完畢后由于選項卡的另外兩張屬于display:none;狀態 所以另外兩張選項卡內echarts的寬高都會變成默認100*100
查閱了很多網上的案例,得出一下一些解決方案:
1:
原因很簡單,在tab頁中,圖表的父容器div是隱藏的(display:none),圖表在執行js初始化的時候找不到這個元素,所以自動將“100%”轉成了“100”,最后計算出來的圖表就成了100px
解決辦法:
找一個在tab頁的切換操作中不會隱藏的父容器,把它的寬度的具體值取出后在初始化圖表之前直接賦給圖表
1 $("#chartMain").css('width',$("#TabContent").width());//獲取父容器的寬度具體數值直接賦值給圖表以達到寬度100%的效果 2 var Chart = echarts.init(document.getElementById('chartMain')); 3 4 // 指定圖表的配置項和數據 5 option = { ...配置項和數據 }; 6 7 // 使用剛指定的配置項和數據顯示圖表。 8 Chart.setOption(option);
2:mychart.resize() 重新渲染高度
3: 后來我想到了問題所在,既然高度是因為display:none;導致的 那大可不必設置這個屬性,但是在頁面渲染完畢后加上即可
所以取消了選項卡的display:none; 但在頁面加載完畢后
window.οnlοad=function(){
根基id在添加css display:none;
}
即可解決,
分割線
---------------------------------------------------------------------
接下來解決一下ifram內外通訊 互相通訊賦值ifram src 和高度問題
統一資源定位符,縮寫為URL,是對網絡資源(網頁、圖像、文件)的引用。URL指定資源位置和檢索資源的機制(http、ftp、mailto)。
舉個例子,這里是這篇文章的 URL 地址:
https://dmitripavlutin.com/parse-url-javascript
很多時候你需要獲取到一段 URL 的某個組成部分。它們可能是 hostname(例如 dmitripavlutin.com),或者 pathname(例如 /parse-url-javascript)。
一個方便的用于獲取 URL 組成部分的辦法是通過 URL() 構造函數。
在這篇文章中,我將給大家展示一段 URL 的結構,以及它的主要組成部分。
接著,我會告訴你如何使用 URL() 構造函數來輕松獲取 URL 的組成部分,比如 hostname,pathname,query 或者 hash。
1. URL 結構
一圖勝千言。不需要過多的文字描述,通過下面的圖片你就可以理解一段 URL 的各個組成部分:
image
2. URL() 構造函數
URL() 構造函數允許我們用它來解析一段 URL:
const url = new URL(relativeOrAbsolute [, absoluteBase]);
參數 relativeOrAbsolute 既可以是絕對路徑,也可以是相對路徑。如果第一個參數是相對路徑的話,那么第二個參數 absoluteBase 則必傳,且必須為第一個參數的絕對路徑。
舉個例子,讓我們用一個絕對路徑的 URL 來初始化 URL() 函數:
const url = new URL('http://example.com/path/index.html');
url.href; // => 'http://example.com/path/index.html'
或者我們可以使用相對路徑和絕對路徑:
const url = new URL('/path/index.html', 'http://example.com');
url.href; // => 'http://example.com/path/index.html'
URL() 實例中的 href 屬性返回了完整的 URL 字符串。
在新建了 URL() 的實例以后,你可以用它來訪問前文圖片中的任意 URL 組成部分。作為參考,下面是 URL() 實例的接口列表:
interface URL {
href: USVString;
protocol: USVString;
username: USVString;
password: USVString;
host: USVString;
hostname: USVString;
port: USVString;
pathname: USVString;
search: USVString;
hash: USVString;
readonly origin: USVString;
readonly searchParams: URLSearchParams;
toJSON(): USVString;
}
上述的 USVString 參數在 JavaScript 中會映射成字符串。
3. Query 字符串
url.search 可以獲取到 URL 當中 ? 后面的 query 字符串:
const url = new URL(
'http://example.com/path/index.html?message=hello&who=world'
);
url.search; // => '?message=hello&who=world'
如果 query 參數不存在,url.search 默認會返回一個空字符串 '':
const url1 = new URL('http://example.com/path/index.html');
const url2 = new URL('http://example.com/path/index.html?');
url1.search; // => ''
url2.search; // => ''
3.1 解析 query 字符串
相比于獲得原生的 query 字符串,更實用的場景是獲取到具體的 query 參數。
獲取具體 query 參數的一個簡單的方法是利用 url.searchParams 屬性。這個屬性是 URLSearchParams 的實例。
URLSearchParams 對象提供了許多用于獲取 query 參數的方法,如get(param),has(param)等。
下面來看個例子:
const url = new URL(
'http://example.com/path/index.html?message=hello&who=world'
);
url.searchParams.get('message'); // => 'hello'
url.searchParams.get('missing'); // => null
url.searchParams.get('message') 返回了 message 這個 query 參數的值——hello。
如果使用 url.searchParams.get('missing') 來獲取一個不存在的參數,則得到一個 null。
4. hostname
url.hostname 屬性返回一段 URL 的 hostname 部分:
const url = new URL('http://example.com/path/index.html');
url.hostname; // => 'example.com'
5. pathname
url. pathname 屬性返回一段 URL 的 pathname 部分:
const url = new URL('http://example.com/path/index.html?param=value');
url.pathname; // => '/path/index.html'
如果這段 URL 不含 path,則該屬性返回一個斜杠 /:
const url = new URL('http://example.com/');
url.pathname; // => '/'
6. hash
最后,我們可以通過 url.hash 屬性來獲取 URL 中的 hash 值:
const url = new URL('http://example.com/path/index.html#bottom');
url.hash; // => '#bottom'
當 URL 中的 hash 不存在時,url.hash 屬性會返回一個空字符串 '':
const url = new URL('http://example.com/path/index.html');
url.hash; // => ''
7. URL 校驗
當使用 new URL() 構造函數來新建實例的時候,作為一種副作用,它同時也會對 URL 進行校驗。如果 URL 不合法,則會拋出一個 TypeError。
舉個例子,http ://example.com 是一段非法 URL,因為它在 http 后面多寫了一個空格。
讓我們用這個非法 URL 來初始化 URL() 構造函數:
try {
const url = new URL('http ://example.com');
} catch (error) {
error; // => TypeError, "Failed to construct URL: Invalid URL"
}
因為 http ://example.com 是一段非法 URL,跟我們想的一樣,new URL() 拋出了一個 TypeError。
8. 修改 URL
除了獲取 URL 的組成部分以外,像 search,hostname,pathname 和 hash 這些屬性都是可寫的——這也意味著你可以修改 URL。
舉個例子,讓我們把一段 URL 從 red.com 修改成 blue.io:
const url = new URL('http://red.com/path/index.html');
url.href; // => 'http://red.com/path/index.html'
url.hostname = 'blue.io';
url.href; // => 'http://blue.io/path/index.html'
注意,在 URL() 實例中只有 origin 和 searchParams 屬性是只讀的,其他所有的屬性都是可寫的,并且會修改原來的 URL。
9. 總結
URL() 構造函數是 JavaScript 中的一個能夠很方便地用于解析(或者校驗)URL 的工具。
new URL(relativeOrAbsolute [, absoluteBase]) 中的第一個參數接收 URL 的絕對路徑或者相對路徑。當第一個參數是相對路徑時,第二個參數必傳且必須為第一個參數的基路徑。
在新建 URL() 的實例以后,你就能很輕易地獲得 URL 當中的大部分組成部分了,比如:
url.search 獲取原生的 query 字符串
url.searchParams 通過 URLSearchParams 的實例去獲取具體的 query 參數
url.hostname獲取 hostname
url.pathname 獲取 pathname
url.hash 獲取 hash 值
那么你最愛用的解析 URL 的 JavaScript 工具又是什么呢?
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
隨著車內屏幕越來越多,越來越大,駕駛者在開車過程中因操作屏幕而分心機率逐漸升高。眾多汽車制造商均希望探索出一種降低或避免「駕駛員分心」的安全性技術。
手勢,是指人手、手和手臂結合產生的動作,作為解決「駕駛者分神」這個痛點的解決方案之一,正在全世界的汽車制造商中掀起「熱浪」。
你只需要隨意的揮一揮手,就能掛斷電話;將手指向順時針或者逆時針方向移動,就能調整音量大小。
汽車手勢的出現,源于對車內屏幕的操作。而這些操作均來自于移動端的設計標準,比如蘋果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%??梢姡跐h字中橫畫是比豎畫多的。所以如果將橫畫刻粗,豎畫刻細的話,可能會使得字體過擠而不美觀。
雖然說橫畫順著木紋,比較不容易斷,可是橫畫的兩端還是會比較容易磨損的,所以工匠們一般會將橫畫的兩端稍微刻大一些,形成飾角。
在明朝,宋體得到了進一步的簡化,原本復雜精細的刀刻技法簡化成了橫、豎和斜三種,所以刻字工匠的門檻大大降低了,宋體字得到了真正的普及。我們同樣來看一下明朝時期的刻本,這是明朝時期汲古閣刻印的《道德指歸論》,這個時候的宋體橫畫已經基本變成水平了,雖然筆畫依舊比較張揚,但是已經少了許多楷體的影子。所以從明朝時期開始的刻本體才能算作真正的宋體。
也是在明朝時期,宋體字傳到了日本,所以現在日本將宋體字稱為明朝體。
清朝是刻本最多的一個朝代,而宋體字在中國真正被確定統一稱為「宋體字」也是發生在清朝。
了解了宋體字的歷史后,我們可以發現宋體字的意義并非只是美觀和易讀而已,他是經過中華民族近千年傳承、優化和改良的文化結晶,他的身上有著厚重的文化氣息。也難怪中國、日本、韓國等受中華文化影響的國家會對宋體有獨特的偏愛。接著我們就正式進入設計宋體字的教程部分,首先我們來了解一下宋體字的主要特征。
從楷體字轉變為宋體,主要產生了三個特征,第一個是橫平豎直,也就是說橫畫是水平的,豎畫是垂直的。第二個特征是橫畫比較細,豎畫比較粗。第三個特征是筆畫上出現了三角形的裝飾角。
可是隨著字體設計的發展,對于宋體的定義已經越來越模糊了。例如上面的這三種字體,雖然他們不完全滿足宋體的特征,可是它們都能算作是宋體。所以我們也不需要對宋體下一個死定義,免得我們在設計字體的時候被定義所束縛住了。
可是仿宋體是不能夠算是宋體字的。我們看仿宋體是不是覺得他和宋朝時期的刻本非常像呢?因為仿宋體是在民國時期,丁善之和丁輔之模仿宋刻本所設計出來的字體,所以仿宋體模仿的是宋朝刻本,而非宋體字,那么仿宋體當然也就不能算在宋體的行列里了。
接著我們來分析一下宋體字的氣質。由于宋體誕生于明朝,具有非常悠長的歷史,而黑體是在民國時期才產生的,所以宋體相對于黑體更能體現傳統感、文化感的氣質屬性。
所以我們做現代風格的設計的時候,可以使用黑體。
而做比較具有傳統風格的設計則可以用宋體。當然也并非說宋體就沒辦法做現代感的設計,通過對宋體體飾和中宮的設計,我們完全可以做出一款現代型的宋體。
先來說一下中宮,我們在之前的教程里說過,中宮越大,越顯現代感,而中宮越小,則越有傳統感。在宋體里也不例外。
我們再來看看這兩個「東」字,很明顯也是左邊的「東」字更現代一些,而右邊的「東」字傳統一些。這兩個字的區別在于體飾的不同。體飾越少越簡潔,宋體就越顯現代;體飾越多越復雜,就越顯傳統。
另外幾何形的體飾也會給宋體帶來現代感。
而傳統宋體字的體飾則是具有手寫感的,線條比較圓滑。
根據體飾和中宮的不同,我們可以大致地將宋體分為三大類。中宮小、體飾多且具有手寫感的宋體歸類為傳統型宋體,中宮大、體飾少且為幾何體飾的則歸類為現代型宋體。而具有一定手寫感的體飾,且中宮偏大的宋體,則歸類為中間型的宋體。
除了中宮和體飾之外,我們還經常調整筆畫粗細去適應宋體字不同的用途。首先我們先來講講正文的宋體。一般正文的字號都是比較小的,如果橫畫過細的話,會使得橫畫幾乎看不見了,而如果橫畫過粗的話,筆畫又會糊在一塊了,所以為了讓宋體字在小字號下也能清晰的顯示,一般橫畫和豎畫的粗細會控制在1:2到1:3左右,最大一般也不會超過1:4。
不過我們設計正文字體的機會還是比較少的,大多數時候我們都是需要設計比較具有張力的標題字。這個時候我們就可以嘗試拉大橫畫和豎畫的粗細差距。當橫畫和豎畫的粗細差距非常大的時候,可以產生較強的視覺沖擊力。畫面中這三款標題宋體,都用了細橫畫搭配粗豎畫。
有時候我們也可以反其道而行之,將橫畫加粗,讓橫畫與豎畫差不多的粗細。這樣我們就可以獲得一款非常醒目的宋體。這樣的宋體有點像比較粗的黑體,既有醒目的特點,也保留了宋體優雅的屬性。
當然,具有張力的標題宋體也并非一定要通過控制橫豎筆畫的粗細來塑造,通過設計一些有張力的體飾,同樣可以讓宋體字變得具有表現力。設計體飾是設計宋體字非常重要的一個環節,因為宋體字的大多數筆畫是存在許多體飾的,我們除了要將體飾設計得好看之外,更重要的是讓不同的體飾和諧共存。如果一個宋體字里存在的體飾都風格不一,那么這個宋體字看著就會不倫不類了。下面我就給大家介紹一個我比較常用的,設計宋體字體飾的方法。
在做字之前,我們要先確定我們想要做的字體的氣質,是傳統的,還是現代的?文藝的還是可愛的?又或者是其他的氣質。因為我們前面也說到,體飾和中宮都會影響字體的氣質,所以我們必須要確定了氣質之后,才能動手去設計字體的中宮和體飾。
另外還要確定字體的用途,需要比較有張力的標題字體,還是需要具備閱讀舒適性的正文字體,那我們也能確定文字的筆畫粗細。
確定好了風格之后,我們就可以開始設計筆畫了。那么我們先來回顧一下,漢字里的八個基本筆畫,我們可以先把這八個筆畫的體飾特征都設計好了,再去拼湊我們想要的字。
一般來說,我們設計宋體會先從橫畫開始設計。因為確定了橫畫之后,體飾的風格、體飾大小、筆畫粗細等很多東西就都可以確定了。
其實宋體中的體飾都是來源于書法中的頓筆,所以我們來看看書法中,橫畫是怎么寫的,書法中的橫在起筆和收筆處分別有一個頓筆。這兩個頓筆分別對應著宋體橫畫首尾的兩處體飾。對于宋體字來說,橫畫末尾的這個體飾是非常重要的,他對整個字體的氣質影響非常的大。
我們前面已經介紹了這兩種襯角分別具有現代感和傳統感。
而這一個的襯角是一個比較圓潤的圓形,他可以用來做比較可愛的宋體。
這一個襯角和剛剛的就正好相反,非常的非常尖銳,適合用來做比較恐怖的宋體。
還有一點要注意的是,如果豎畫越粗的話,橫畫的襯角一般也要相應的變大一些。
因為宋體的橫畫本來就已經很細了,如果襯角還非常小的話,橫畫很容易就會被忽略掉了,橫畫末端的這個三角形起到了一定強調橫線的作用。當然如果是故意要設計成小襯角或者無襯角的話就另當別論了。
橫畫做好之后,就可以開始設計豎畫了。在書法中,豎畫在起筆處會有一個頓筆,而收筆的地方會稍微往左側偏一些,這樣分別形成了宋體中豎畫起筆和收筆的兩處體飾。
那么我們應該怎么用橫畫推導出豎畫呢?橫畫和豎畫關聯度最大的地方在橫畫三角形襯角和豎畫上方襯角的這個地方。例如這一組都是直線加切角。
而這組都是曲線加圓角。
另外我們還能將這兩個地方給聯系起來,因為他們都是起筆的位置。如果橫畫的起筆是水平的話,那么豎畫的起筆就應該是垂直的。
而如果橫畫的起筆是往外擴的話,那么豎畫的起筆也可以往外擴張。
我一般還會將豎畫的起筆和收筆的的地方關聯起來,如果起筆是垂直的,那么收筆我也會設置成垂直的。
而如果起筆往外擴的話,那么收筆我也會往外擴形成書寫曲線,這樣整個豎畫能看起來平衡一些。
接著來設計橫折。書法中在這個轉折的地方會有一個頓筆。所以在宋體的橫折處也會形成一個裝飾角。
其實橫折這個筆畫在設計好橫畫和豎畫之后基本就已經出來了。只要將他們組合在一起,然后將橫畫的襯角往回縮小一些,橫折就做好了。
講完了橫折我們順便也講一下這種口字的結構好了。口字結構由剛剛做好的橫折加上一個豎線和一個去掉三角襯角的橫線組成。然后我們需要做一些細微的調整。豎筆體飾的這個地方需要往上收一些,不要漏出來,這樣的筆畫看著能干凈一些。
然后豎畫入筆的地方也要往上提一些,讓左右兩邊的體飾能夠平衡。
最后加上橫畫,把襯角的部分裁去,注意兩個豎線需要出頭一些。這個口字就完成了。
然后來做撇和捺。書法里的撇起筆的地方有一個頓筆,所以宋體里,撇有一處體飾。
書法里捺則在起筆和收筆處各有一處轉折。所以宋體里,捺則有兩處體飾。
撇基本上可以從豎線輕易地推導出來,因為他們的起筆都是一樣的,只要稍微調整一下起筆的角度就可以了。
而捺與撇是正好相反的,起筆細,收筆粗,所以捺的起筆需要縮小一些,但是需要保證這兩個地方是相同的。而捺的收筆是一個比較獨立的地方,只需要風格保持大致一致就好了。
接著來做提。在書法中,提的起筆一般是會有一個頓筆的,這一個頓筆與豎的起筆的頓筆是類似,所以在宋體中,提的起筆會有一個與豎類似的體飾。
提與豎起筆的體飾是差不多的,只是方向不同而已。
最后就只剩下點和鉤兩個基礎筆畫還沒設計了。這兩個筆畫和別的筆畫之間的聯系不太大,同樣也只需要保持整體筆畫風格一致就好了。不過點和鉤之間卻存在著一定的聯系的。最主要的是體現在這個地方,如果是尖角,那么點和鉤最好都統一為尖角。
而如果點是圓滑過渡的,那么鉤最好也是圓角。
另外還有如果點的這個位置是比較飽滿的話,那么鉤轉折的位置也應該設計得飽滿一些。
而如果是瘦瘦的點,鉤轉折的位置也要相應的瘦一些。
最后還有一個需要統一的地方,就是撇、點、鉤等筆畫的收筆必須要保持一致??梢允菆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界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
藍藍設計的小編 http://www.syprn.cn