cbba申请找回微信账号密码码忘记了怎么找回

跪求有注册码破解.rar软件
本回答由提问者推荐
var sogou_ad_id=731547;
var sogou_ad_height=160;
var sogou_ad_width=690;《好看》依托百度技术,精准推荐优质短视频内容,懂你所好,量身打造最适合你的短视频客户端!&figure&&img src=&https://pic2.zhimg.com/v2-aee916a9c4c_b.jpg& data-rawwidth=&900& data-rawheight=&500& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&https://pic2.zhimg.com/v2-aee916a9c4c_r.jpg&&&/figure&&h2&&b&Taro 是什么?&/b&&/h2&&p&Taro 是由 &b&凹凸实验室&/b& 打造的一套遵循 React 语法规范的多端统一开发框架。&/p&&p&现如今市面上端的形态多种多样,Web、App 端(React Native)、微信小程序等各种端大行其道,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。&/p&&p&使用 Taro,我们可以只书写一套代码,再通过 Taro 的编译工具,将源代码分别编译出可以在不同端(微信小程序、H5、App 端等)运行的代码。同时 Taro 还提供开箱即用的语法检测和自动补全等功能,有效地提升了开发体验和开发效率。&/p&&hr&&h2&&b&Taro 能提供什么?&/b&&/h2&&h2&&b&一次编写,多端运行&/b&&/h2&&p&既然是一个多端解决方案,Taro 最重要的能力当然是写一套代码输出多端皆可运行的代码。目前 Taro 已经支持一套代码同时生成 H5 和小程序,App端(React Native)端也即将支持,同时诸如快应用等端也将得到支持。&/p&&p&同时 Taro 也已经投入到了生产环境使用,目前已经支撑了一个 3 万行代码小程序 &a href=&https://link.zhihu.com/?target=https%3A//www.toplife.com/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TOPLIFE&/a& 的开发并上线。京东购物 小程序和 一起有局 小程序也在使用 Taro 部分重构中,即将上线。未来也将接入更多业务。&/p&&p&&br&&/p&&figure&&img src=&https://pic4.zhimg.com/v2-abbde29f5e11c56e8409f3_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&2022& data-rawheight=&686& class=&origin_image zh-lightbox-thumb& width=&2022& data-original=&https://pic4.zhimg.com/v2-abbde29f5e11c56e8409f3_r.jpg&&&/figure&&p&&br&&/p&&p&&br&&/p&&h2&&b&现代前端开发流程&/b&&/h2&&p&和微信自带的小程序框架不一样,Taro 积极拥抱社区现有的现代开发流程,包括但不限于:&/p&&ul&&li&NPM 包管理系统&/li&&li&ES6+ 语法&/li&&li&自由的资源引用&/li&&li&CSS 预处理器和后处理器(SCSS、Less、PostCSS)&/li&&/ul&&p&对于微信小程序的编译流程,我们从 &a href=&https://link.zhihu.com/?target=https%3A//parceljs.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Parcel&/a& 得到灵感,自研了一套打包机制将 AST 不断传递,因此代码分析的速度得到了很大的提高。一台 2015 年 的 15寸 RMBP 在编译上百个组件时仅需要大约 15 秒左右。&/p&&h2&&b&和 React 完全一致的 API 和组件化系统&/b&&/h2&&p&在 Taro 中,你不用像小程序一样区分什么是 &code&App&/code& 组件,什么是 &code&Page&/code& 组件,什么是 &code&Component&/code& 组件,Taro 全都是 &code&Component&/code& 组件,并且和 React 的生命周期完全一致。可以说,一旦你掌握了 React,那就几乎掌握了 Taro。而学习 React 的资源也几乎是汗牛充栋,完全不用担心学不会。&/p&&p&Taro 和 React 一样,同样使用声明式的 JSX 语法。相比起字符串的模板语法,JSX 在处理精细复杂需求的时候会更得心应手。&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&c1&&// 一个典型的 Taro 组件&/span&
&span class=&kr&&import&/span& &span class=&nx&&Taro&/span&&span class=&p&&,&/span& &span class=&p&&{&/span& &span class=&nx&&Component&/span& &span class=&p&&}&/span& &span class=&nx&&from&/span& &span class=&s1&&'@tarojs/taro'&/span&
&span class=&kr&&import&/span& &span class=&p&&{&/span& &span class=&nx&&View&/span&&span class=&p&&,&/span& &span class=&nx&&Button&/span& &span class=&p&&}&/span& &span class=&nx&&from&/span& &span class=&s1&&'@tarojs/components'&/span&
&span class=&kr&&export&/span& &span class=&k&&default&/span& &span class=&kr&&class&/span& &span class=&nx&&Home&/span& &span class=&kr&&extends&/span& &span class=&nx&&Component&/span& &span class=&p&&{&/span&
&span class=&nx&&constructor&/span& &span class=&p&&(&/span&&span class=&nx&&props&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&kr&&super&/span&&span class=&p&&(&/span&&span class=&nx&&props&/span&&span class=&p&&)&/span&
&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&state&/span& &span class=&o&&=&/span& &span class=&p&&{&/span&
&span class=&nx&&title&/span&&span class=&o&&:&/span& &span class=&s1&&'首页'&/span&&span class=&p&&,&/span&
&span class=&nx&&list&/span&&span class=&o&&:&/span& &span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&,&/span& &span class=&mi&&2&/span&&span class=&p&&,&/span& &span class=&mi&&3&/span&&span class=&p&&]&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&nx&&componentWillMount&/span& &span class=&p&&()&/span& &span class=&p&&{}&/span&
&span class=&nx&&componentDidMount&/span& &span class=&p&&()&/span& &span class=&p&&{}&/span&
&span class=&nx&&componentWillUpdate&/span& &span class=&p&&(&/span&&span class=&nx&&nextProps&/span&&span class=&p&&,&/span& &span class=&nx&&nextState&/span&&span class=&p&&)&/span& &span class=&p&&{}&/span&
&span class=&nx&&componentDidUpdate&/span& &span class=&p&&(&/span&&span class=&nx&&prevProps&/span&&span class=&p&&,&/span& &span class=&nx&&prevState&/span&&span class=&p&&)&/span& &span class=&p&&{}&/span&
&span class=&nx&&shouldComponentUpdate&/span& &span class=&p&&(&/span&&span class=&nx&&nextProps&/span&&span class=&p&&,&/span& &span class=&nx&&nextState&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&kc&&true&/span&
&span class=&p&&}&/span&
&span class=&nx&&add&/span& &span class=&o&&=&/span& &span class=&p&&(&/span&&span class=&nx&&e&/span&&span class=&p&&)&/span& &span class=&o&&=&&/span& &span class=&p&&{&/span&
&span class=&c1&&// dosth&/span&
&span class=&p&&}&/span&
&span class=&nx&&render&/span& &span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&kr&&const&/span& &span class=&p&&{&/span& &span class=&nx&&list&/span&&span class=&p&&,&/span& &span class=&nx&&title&/span& &span class=&p&&}&/span& &span class=&o&&=&/span& &span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&state&/span&
&span class=&k&&return&/span& &span class=&p&&(&/span&
&span class=&o&&&&/span&&span class=&nx&&View&/span& &span class=&nx&&className&/span&&span class=&o&&=&/span&&span class=&s1&&'index'&/span&&span class=&o&&&&/span&
&span class=&o&&&&/span&&span class=&nx&&View&/span& &span class=&nx&&className&/span&&span class=&o&&=&/span&&span class=&s1&&'title'&/span&&span class=&o&&&&/span&&span class=&p&&{&/span&&span class=&nx&&title&/span&&span class=&p&&}&/span&&span class=&o&&&&/span&&span class=&err&&/View&&/span&
&span class=&o&&&&/span&&span class=&nx&&View&/span& &span class=&nx&&className&/span&&span class=&o&&=&/span&&span class=&s1&&'content'&/span&&span class=&o&&&&/span&
&span class=&p&&{&/span&&span class=&nx&&list&/span&&span class=&p&&.&/span&&span class=&nx&&map&/span&&span class=&p&&(&/span&&span class=&nx&&item&/span& &span class=&o&&=&&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&p&&(&/span&
&span class=&o&&&&/span&&span class=&nx&&View&/span& &span class=&nx&&className&/span&&span class=&o&&=&/span&&span class=&s1&&'item'&/span&&span class=&o&&&&/span&&span class=&p&&{&/span&&span class=&nx&&item&/span&&span class=&p&&}&/span&&span class=&o&&&&/span&&span class=&err&&/View&&/span&
&span class=&p&&)&/span&
&span class=&p&&})}&/span&
&span class=&o&&&&/span&&span class=&nx&&Button&/span& &span class=&nx&&className&/span&&span class=&o&&=&/span&&span class=&s1&&'add'&/span& &span class=&nx&&onClick&/span&&span class=&o&&=&/span&&span class=&p&&{&/span&&span class=&k&&this&/span&&span class=&p&&.&/span&&span class=&nx&&add&/span&&span class=&p&&}&/span&&span class=&o&&&&/span&&span class=&nx&&添加&/span&&span class=&o&&&&/span&&span class=&err&&/Button&&/span&
&span class=&o&&&&/span&&span class=&err&&/View&&/span&
&span class=&o&&&&/span&&span class=&err&&/View&&/span&
&span class=&p&&)&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&&b&良好的开发效率和体验&/b&&/h2&&p&鉴于 Taro 的语法和 React 完全一样,因此编辑器/IDE 能够对 Taro 的支持和 React 是几乎一样的。现代的编辑器默认都对 JSX 进行了支持,如果没有,找一个插件也是非常容易的事情。但毕竟我们做 Taro 就是为了提升开发效率和开发体验,而真正使用 Taro 的人就是我们自己或正坐在我们旁边的同事。因此在此基础上,我们又对 Taro 开发体验进行了进一步加强。&/p&&p&&br&&/p&&p&&b&自定义 ESLint 规则&/b&&/p&&p&我们之前提到过,当学会了 React,其实也差不多会 Taro 了。其中很重要的一个原因就是我们对 Taro 不支持的语法和特性单独写了 ESLint 规则:开发者只管写代码,写到不支持的语法/特性编辑器会报错,并给出报错信息和一个文档地址描述。&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-5cd141ad1cbba2e0ba19aaf_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&480& data-rawheight=&304& data-thumbnail=&https://pic1.zhimg.com/v2-5cd141ad1cbba2e0ba19aaf_b.jpg& class=&origin_image zh-lightbox-thumb& width=&480& data-original=&https://pic1.zhimg.com/v2-5cd141ad1cbba2e0ba19aaf_r.jpg&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&&b&类型安全和运行时检测&/b&&/p&&p&JSX 的本质就是 JavaScript 的语法增强,所以例如没有 &code&import&/code& 组件等语法错误在编译期就能发现。开发者也可以使用 &code&TypeScript&/code& 或 &code&Flow&/code& 来对代码的可靠性进一步增强,或使用 &code&PropsType&/code& 在运行时进一步保障代码的鲁棒性。&/p&&p&&br&&/p&&figure&&img src=&https://pic1.zhimg.com/v2-aec790e71f1d9d4a7ae1_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&480& data-rawheight=&376& data-thumbnail=&https://pic1.zhimg.com/v2-aec790e71f1d9d4a7ae1_b.jpg& class=&origin_image zh-lightbox-thumb& width=&480& data-original=&https://pic1.zhimg.com/v2-aec790e71f1d9d4a7ae1_r.jpg&&&/figure&&p&&br&&/p&&p&&br&&/p&&p&&b&高效的自动补全和 ES6+ 语法&/b&&/p&&p&Taro 的所有 API(包括微信小程序等端能力接口)都有智能的提醒和自动补全,包括接口的参数和返回值。&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-24bc98d8a298b9c585b293_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&480& data-rawheight=&376& data-thumbnail=&https://pic2.zhimg.com/v2-24bc98d8a298b9c585b293_b.jpg& class=&origin_image zh-lightbox-thumb& width=&480& data-original=&https://pic2.zhimg.com/v2-24bc98d8a298b9c585b293_r.jpg&&&/figure&&p&&br&&/p&&hr&&h2&&b&Taro 的设计思路&/b&&/h2&&p&我们的初心就是做一款能够适配多端的解决方案,结合业务场景、技术选型和前端历史发展进程,我们的解决方案必须满足下述要求:&/p&&ul&&li&代码多端复用,不仅能运行在时下最热门的 H5、微信小程序、React Native,对其他可能会流行的端也留有余地和可能性。&/li&&li&完善和强大的组件化机制,这是开发复杂应用的基石。&/li&&li&与目前团队技术栈有机结合,有效提高效率。&/li&&li&学习成本足够低&/li&&li&背后的生态强大&/li&&/ul&&p&同时满足这几个需求并不容易,在我们经过充分地调研和思考之后发现只有 React 体系能够满足我们的需求。而对于微信小程序而言,使用 React 完全没有办法进行开发——直到我们从 &a href=&https://link.zhihu.com/?target=https%3A//github.com/facebook/codemod& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&codemod&/a& 得到灵感:&/p&&p&&br&&/p&&blockquote&在一个优秀且严格的规范限制下,从更高抽象的视角(语法树)来看,每个人写的代码都差不多。&/blockquote&&p&&br&&/p&&p&也就是说,对于微信小程序这样不开放不开源的端,我们可以先把 React 代码分析成一颗抽象语法树,根据这颗树生成小程序支持的模板代码,再做一个小程序运行时框架处理事件和生命周期与小程序框架兼容,然后把业务代码跑在运行时框架就完成了小程序端的适配。&/p&&p&对于 React 已经支持的端,例如 Web、React Native 甚至未来的 React VR,我们只要包一层组件库再做些许样式支持即可。鉴于时下小程序的热度和我们团队本身的业务侧重程度,组件库的 API 是以小程序为标准,其他端的组件库的 API 都会和小程序端的组件保持一致。&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-c56ffe56f3f61a479ba27b5a6b22d789_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1378& data-rawheight=&1324& class=&origin_image zh-lightbox-thumb& width=&1378& data-original=&https://pic2.zhimg.com/v2-c56ffe56f3f61a479ba27b5a6b22d789_r.jpg&&&/figure&&hr&&h2&&b&技术选型与权衡&/b&&/h2&&p&在我们前面社区已经有多个优秀的框架以小程序为核心对多端适配进行了探索,我们将各个开发框架的主要特点和特性进行了对比并制成图表。大家可以结合团队技术栈、技术需求以及框架特点、特性进行选型和权衡。&/p&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-e6eff4b00d6_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&2042& data-rawheight=&1508& class=&origin_image zh-lightbox-thumb& width=&2042& data-original=&https://pic2.zhimg.com/v2-e6eff4b00d6_r.jpg&&&/figure&&hr&&h2&&b&结语&/b&&/h2&&p&经过数个月的开发,Taro 从第一次 commit 到发展成包括 16 个包,十多位同学共同参与的大型项目。与此同时,Taro 也在生产环境支撑了数个复杂业务线上项目的开发,将来也会支撑更多业务。&/p&&p&Taro 的技术方案和实现也根植于社区,我们也希望为技术社区的发展壮大贡献一份自己的力量。秉持着凹凸实验室长久以来开源、开放、共享的优良传统,我们今天将 Taro 全部代码开源,为广大开发者快速开发多端项目提供一整套技术解决方案。未来,我们也将继续拓展 Taro 现有能力,支持更多端能力,继续完善开发者体验,提高开发者效率,帮助更多开发者,同时也从社区中汲取养分,让 Taro 变得更加强大。&/p&&p&&br&&/p&&p&官网:&a href=&https://link.zhihu.com/?target=http%3A//taro.aotu.io/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&taro.aotu.io/&/span&&span class=&invisible&&&/span&&/a&&/p&&p&GitHub:
&a href=&https://link.zhihu.com/?target=http%3A//github.com/nervjs/taro& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&github.com/nervjs/taro&/span&&span class=&invisible&&&/span&&/a&&/p&&p&如果你还没听过 Nerv,可以来这里看看:&a href=&https://link.zhihu.com/?target=https%3A//nerv.aotu.io/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&nerv.aotu.io/&/span&&span class=&invisible&&&/span&&/a&&/p&
Taro 是什么?Taro 是由 凹凸实验室 打造的一套遵循 React 语法规范的多端统一开发框架。现如今市面上端的形态多种多样,Web、App 端(React Native)、微信小程序等各种端大行其道,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代…
&figure&&img src=&https://pic2.zhimg.com/v2-389de2bcaa4edf6a2b85b523e6d54dc4_b.jpg& data-rawwidth=&1006& data-rawheight=&385& class=&origin_image zh-lightbox-thumb& width=&1006& data-original=&https://pic2.zhimg.com/v2-389de2bcaa4edf6a2b85b523e6d54dc4_r.jpg&&&/figure&&p&PostCSS 是使用 javascript 插件转换 CSS 的后处理器。PostCSS 本身不会对你的 CSS 做任何事情,你需要安装一些 plugins 才能开始工作。这不仅使其模块化,同时功能加强。&/p&&p&cssnext 是一个 CSS transpiler,允许你使用最新的 CSS 语法。cssnext 把新 CSS 规范转换成兼容性更强的 CSS,所以不需要等待各种浏览器的支持。&/p&&p&PostCSS 的工作原理就是解析 CSS 并将其转换成一个 CSS 的节点数,这可以通过 javascript 来控制,然后返回修改后的树并保存。它与 Sass(预处理器)的工作原理不同,你基本上是用一种不同的语言来编译 CSS。&/p&&figure&&img src=&https://pic2.zhimg.com/v2-5bceeaa189b26ed5e169cc_b.jpg& data-caption=&& data-size=&small& data-rawwidth=&720& data-rawheight=&300& class=&origin_image zh-lightbox-thumb& width=&720& data-original=&https://pic2.zhimg.com/v2-5bceeaa189b26ed5e169cc_r.jpg&&&/figure&&h2&预处理和后处理的区别:&/h2&&p&为了简单的方式解释预处理和后处理的不同,这里以单位转换为例。当书写 Sass 时,我们可以用函数&code&px&/code&转换成&code&rem&/code&:&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&c&&/* input */&/span&
&span class=&nc&&.selector&/span& &span class=&p&&{&/span& &span class=&nb&&margin-bottom&/span&&span class=&o&&:&/span& &span class=&n&&rem&/span&&span class=&p&&(&/span&&span class=&m&&20px&/span&&span class=&p&&);&/span& &span class=&p&&}&/span&
&span class=&c&&/* output, assuming base font size is 1rem */&/span&
&span class=&nc&&.selector&/span& &span class=&p&&{&/span& &span class=&nb&&margin-bottom&/span&&span class=&o&&:&/span& &span class=&m&&1&/span&&span class=&o&&.&/span&&span class=&m&&25&/span&&span class=&n&&rem&/span&&span class=&p&&;&/span& &span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&这种方式节省了我们手工计算的时间。不过通过 PostCSS,我们能够做的更好。因为是后处理的缘故,我们不需要任何函数来编译 CSS。我们可以直接书写&code&px&/code&,它可以自动地转换成&code&rem&/code&。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&c&&/* input */&/span&
&span class=&nc&&.selector&/span& &span class=&p&&{&/span& &span class=&nb&&margin-bottom&/span&&span class=&o&&:&/span& &span class=&m&&20px&/span&&span class=&p&&;&/span& &span class=&p&&}&/span&
&span class=&c&&/* output, assuming base font size is 1rem */&/span&
&span class=&nc&&.selector&/span& &span class=&p&&{&/span& &span class=&nb&&margin-bottom&/span&&span class=&o&&:&/span& &span class=&m&&1&/span&&span class=&o&&.&/span&&span class=&m&&25&/span&&span class=&n&&rem&/span&&span class=&p&&;&/span& &span class=&p&&}&/span&
&/code&&/pre&&/div&&p&PostCSS 会在每一个&code&px&/code&值出现并运行计算之前处理声明,将其转换成&code&rem&/code&的值。&/p&&hr&&h2&cssnext 新特性:&/h2&&p&&b&cssnext 包含了大量的新特性:&/b&&/p&&ul&&li&自动提供浏览器前缀支持&/li&&li&自定义属性与 var() 支持&/li&&li&自定义属性集合与 @apply 支持&/li&&li&简化的、更安全的 calc()&/li&&li&可自定义的媒体查询&/li&&li&媒体查询范围&/li&&li&自定义选择器&/li&&li&嵌套&/li&&li&image-set()&/li&&li&color()&/li&&li&hwb()&/li&&li&gray()&/li&&li&rrggbbaa 颜色&/li&&li&rgba() 的降级方案&/li&&li&rebeccapurple 颜色&/li&&li&font-variant 属性&/li&&li&filter 属性&/li&&li&inital 值&/li&&li&rem 单位的降级方案&/li&&li&:any-link 伪类&/li&&li&:mathces 伪类&/li&&li&:not 伪类&/li&&li&:: 伪元素语法的降级方案&/li&&li&overflow-wrap 属性的降级方案&/li&&li&不区分大小写的属性&/li&&li&功能增强的 rga()&/li&&li&功能增强的 hsl()&/li&&li&sysem-ui 字体&/li&&/ul&&p&&br&&/p&&h2&自动提供浏览器前缀支持:&/h2&&p&自动添加(以及删除过时/没用的前缀),由 autoprefixer 实现&/p&&p&&br&&/p&&h2&自定义属性与 var() 支持:&/h2&&p&自定义属性的当前转换旨在提供一种限定在&code&:root&/code&选择器中、面向未来的、由原生 CSS 自定义属性提供的新特性。&/p&&p&&br&&/p&&p&使用特性:&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nd&&:root&/span& &span class=&p&&{&/span&
&span class=&o&&--&/span&&span class=&n&&mainColor&/span&&span class=&o&&:&/span& &span class=&nb&&red&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&nt&&a&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&n&&var&/span&&span class=&p&&(&/span&&span class=&o&&--&/span&&span class=&n&&mainColor&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&&br&&/p&&h2&自定义属性集合与 @apply 支持:&/h2&&p&允许你在已命名的自定义属性中存储一套变量,然后在其他类型规则中引用它。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nd&&:root&/span& &span class=&p&&{&/span&
&span class=&o&&--&/span&&span class=&n&&danger&/span&&span class=&o&&-&/span&&span class=&n&&theme&/span&&span class=&o&&:&/span& &span class=&err&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&nb&&white&/span&&span class=&p&&;&/span&
&span class=&nb&&background-color&/span&&span class=&o&&:&/span& &span class=&nb&&red&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&&span class=&o&&;&/span&
&span class=&err&&}&/span&
&span class=&nc&&.danger&/span& &span class=&p&&{&/span&
&span class=&o&&@&/span&&span class=&n&&apply&/span& &span class=&o&&--&/span&&span class=&n&&danger&/span&&span class=&o&&-&/span&&span class=&n&&theme&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&&br&&/p&&h2&简化的、更安全的 calc():&/h2&&p&使用优化预分析 var() 引用来允许你更安全的用 calc() 使用自定义变量&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nd&&:root&/span& &span class=&p&&{&/span&
&span class=&o&&--&/span&&span class=&n&&fontSize&/span&&span class=&o&&:&/span& &span class=&m&&1&/span&&span class=&n&&rem&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&nt&&h1&/span& &span class=&p&&{&/span&
&span class=&nb&&font-size&/span&&span class=&o&&:&/span& &span class=&n&&calc&/span&&span class=&p&&(&/span&&span class=&n&&var&/span&&span class=&p&&(&/span&&span class=&o&&--&/span&&span class=&n&&fontSize&/span&&span class=&p&&)&/span& &span class=&o&&*&/span& &span class=&m&&2&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&可自定义的媒体查询&/h2&&p&一个更好的方法来实现语义化的媒体查询&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&k&&@custom-media&/span& &span class=&nt&&--small-viewport&/span& &span class=&o&&(&/span&&span class=&nt&&max-width&/span&&span class=&o&&:&/span& &span class=&nt&&30em&/span&&span class=&o&&)&/span&&span class=&p&&;&/span&
&span class=&c&&/* check out media queries ranges for a better syntax !*/&/span&
&span class=&k&&@media&/span& &span class=&o&&(&/span&&span class=&nt&&--small-viewport&/span&&span class=&o&&)&/span& &span class=&p&&{&/span&
&span class=&c&&/* styles for small viewport */&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&媒体查询范围:&/h2&&p&允许用 &code&&=&/code& 和 &code&&=&/code&来取代&code&min&/code&和&code&max&/code& &/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&k&&@media&/span& &span class=&o&&(&/span&&span class=&nt&&width&/span& &span class=&o&&&=&/span& &span class=&nt&&500px&/span&&span class=&o&&)&/span& &span class=&nt&&and&/span& &span class=&o&&(&/span&&span class=&nt&&width&/span& &span class=&o&&&=&/span& &span class=&nt&&1200px&/span&&span class=&o&&)&/span& &span class=&p&&{&/span&
&span class=&c&&/* your styles */&/span&
&span class=&p&&}&/span&
&span class=&c&&/* or coupled with custom media queries */&/span&
&span class=&k&&@custom-media&/span& &span class=&nt&&--only-medium-screen&/span& &span class=&o&&(&/span&&span class=&nt&&width&/span& &span class=&o&&&=&/span& &span class=&nt&&500px&/span&&span class=&o&&)&/span& &span class=&nt&&and&/span& &span class=&o&&(&/span&&span class=&nt&&width&/span& &span class=&o&&&=&/span& &span class=&nt&&1200px&/span&&span class=&o&&)&/span&&span class=&p&&;&/span&
&span class=&k&&@media&/span& &span class=&o&&(&/span&&span class=&nt&&--only-medium-screen&/span&&span class=&o&&)&/span& &span class=&p&&{&/span&
&span class=&c&&/* your styles */&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&h2&自定义选择器:&/h2&&p&允许你创造自己的选择器&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&k&&@custom-selector&/span& &span class=&nd&&:--button&/span& &span class=&nt&&button&/span&&span class=&o&&,&/span& &span class=&nc&&.button&/span&&span class=&p&&;&/span&
&span class=&k&&@custom-selector&/span& &span class=&nd&&:--enter&/span& &span class=&nd&&:hover&/span&&span class=&o&&,&/span& &span class=&nd&&:focus&/span&&span class=&p&&;&/span&
&span class=&nd&&:--button&/span& &span class=&p&&{&/span&
&span class=&c&&/* styles for your buttons */&/span&
&span class=&p&&}&/span&
&span class=&nd&&:--button:--enter&/span& &span class=&p&&{&/span&
&span class=&c&&/*&/span&
&span class=&c&&
hover/focus styles for your button&/span&
&span class=&c&&
Read more about :enter proposal&/span&
&span class=&c&&
http://discourse.specifiction.org/t/a-common-pseudo-class-for-hover-and-focus/877&/span&
&span class=&c&&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&嵌套:&/h2&&p&允许你使用嵌套选择器&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&a&/span& &span class=&p&&{&/span&
&span class=&c&&/* direct nesting (& MUST be the first part of selector)*/&/span&
&span class=&o&&&&/span& &span class=&n&&span&/span& &span class=&err&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&nb&&white&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&c&&/* @nest rule (for complex nesting) */&/span&
&span class=&k&&@nest&/span& &span class=&nt&&span&/span& &span class=&o&&&&/span& &span class=&p&&{&/span&
&span class=&nt&&color&/span&&span class=&o&&:&/span& &span class=&nt&&blue&/span&&span class=&o&&;&/span&
&span class=&p&&}&/span&
&span class=&c&&/* media query automatic nesting */&/span&
&span class=&k&&@media&/span& &span class=&o&&(&/span&&span class=&nt&&min-width&/span&&span class=&o&&:&/span& &span class=&nt&&30em&/span&&span class=&o&&)&/span& &span class=&p&&{&/span&
&span class=&nt&&color&/span&&span class=&o&&:&/span& &span class=&nt&&yellow&/span&&span class=&o&&;&/span&
&span class=&p&&}&/span&
&span class=&err&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&image-set() 函数:&/h2&&p&允许你根据不同的用户设备来提供不同的图片解决方案&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nc&&.foo&/span& &span class=&p&&{&/span&
&span class=&nb&&background-image&/span&&span class=&o&&:&/span& &span class=&n&&image&/span&&span class=&o&&-&/span&&span class=&n&&set&/span&&span class=&p&&(&/span&&span class=&sx&&url(img/test.png)&/span& &span class=&m&&1&/span&&span class=&n&&x&/span&&span class=&o&&,&/span&
&span class=&sx&&url(img/test-2x.png)&/span& &span class=&m&&2&/span&&span class=&n&&x&/span&&span class=&o&&,&/span&
&span class=&sx&&url(my-img-print.png)&/span& &span class=&m&&600&/span&&span class=&n&&dpi&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&&br&&/p&&h2&color() 函数:&/h2&&p&一个颜色函数来修改颜色&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&a&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&nb&&color&/span&&span class=&p&&(&/span&&span class=&nb&&red&/span& &span class=&n&&alpha&/span&&span class=&p&&(&/span&&span class=&m&&-10%&/span&&span class=&p&&));&/span&
&span class=&p&&}&/span&
&span class=&nt&&a&/span&&span class=&nd&&:hover&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&nb&&color&/span&&span class=&p&&(&/span&&span class=&nb&&red&/span& &span class=&n&&blackness&/span&&span class=&p&&(&/span&&span class=&m&&80%&/span&&span class=&p&&));&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&hwb() 函数&/h2&&p&与 hs1() 相似,不过更容易阅读&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&body&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&n&&hwb&/span&&span class=&p&&(&/span&&span class=&m&&90&/span&&span class=&o&&,&/span& &span class=&m&&0%&/span&&span class=&o&&,&/span& &span class=&m&&0%&/span&&span class=&o&&,&/span& &span class=&m&&0&/span&&span class=&o&&.&/span&&span class=&m&&5&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&gray() 函数:&/h2&&p&允许你使用超过50种渐变的灰度值,对于第一个参数,你可以使用 0 - 255 的数值或者百分比。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nc&&.foo&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&nb&&gray&/span&&span class=&p&&(&/span&&span class=&m&&85&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&nc&&.bar&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&nb&&gray&/span&&span class=&p&&(&/span&&span class=&m&&10%&/span&&span class=&o&&,&/span& &span class=&m&&50%&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&rrggbbaa 颜色值:&/h2&&p&允许使用4位或者8位十六进制数来表示颜色&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&body&/span& &span class=&p&&{&/span&
&span class=&nb&&background&/span&&span class=&o&&:&/span& &span class=&m&&#9d9c&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&rgba() 的降级方案:&/h2&&p&如果你使用的是旧的浏览器(比如 IE8),那么把 rgba() 转换为实体颜色&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&body&/span& &span class=&p&&{&/span&
&span class=&nb&&background&/span&&span class=&o&&:&/span& &span class=&n&&rgba&/span&&span class=&p&&(&/span&&span class=&m&&153&/span&&span class=&o&&,&/span& &span class=&m&&221&/span&&span class=&o&&,&/span& &span class=&m&&153&/span&&span class=&o&&,&/span& &span class=&m&&0&/span&&span class=&o&&.&/span&&span class=&m&&8&/span&&span class=&p&&);&/span&
&span class=&c&&/* you will have the same value without alpha as a fallback */&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&rebeccapurple 颜色:&/h2&&p&允许你使用新的颜色关键词&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&body&/span& &span class=&p&&{&/span&
&span class=&nb&&background&/span&&span class=&o&&:&/span& &span class=&n&&rgba&/span&&span class=&p&&(&/span&&span class=&m&&153&/span&&span class=&o&&,&/span& &span class=&m&&221&/span&&span class=&o&&,&/span& &span class=&m&&153&/span&&span class=&o&&,&/span& &span class=&m&&0&/span&&span class=&o&&.&/span&&span class=&m&&8&/span&&span class=&p&&);&/span&
&span class=&c&&/* you will have the same value without alpha as a fallback */&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&font-variant 属性:&/h2&&p&通过 &code&font-feature-settings&/code&降级的一种属性。你可以通过这个链接来查看浏览器支持&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&h2&/span& &span class=&p&&{&/span&
&span class=&nb&&font-variant&/span&&span class=&o&&-&/span&&span class=&n&&caps&/span&&span class=&o&&:&/span& &span class=&nb&&small-caps&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&nt&&table&/span& &span class=&p&&{&/span&
&span class=&nb&&font-variant&/span&&span class=&o&&-&/span&&span class=&n&&numeric&/span&&span class=&o&&:&/span& &span class=&n&&lining&/span&&span class=&o&&-&/span&&span class=&n&&nums&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&filter 属性:&/h2&&p&W3C 的 filters 只允许使用&code&url(data:*)&/code&来转换 svg filter。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nc&&.blur&/span& &span class=&p&&{&/span&
&span class=&n&&filter&/span&&span class=&o&&:&/span& &span class=&n&&blur&/span&&span class=&p&&(&/span&&span class=&m&&4px&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&inital 值:&/h2&&p&允许你使用如何值的初始值。该值表示属性初始化值所指定的值,但这并不意味着浏览器的默认值。&/p&&p&比如,对于&code&display&/code&属性,initial 时钟标示内联,因为这是属性指定的初始值。一个例子,&code&div { display: initial }&/code&并不代表&code&block&/code&,而是&code&inline&/code&。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&div&/span& &span class=&p&&{&/span&
&span class=&nb&&display&/span&&span class=&o&&:&/span& &span class=&n&&initial&/span&&span class=&p&&;&/span& &span class=&c&&/* inline */&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&rem 单位:&/h2&&p&在旧浏览器里将 rem 降级为 px(比如IE8)&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&h1&/span& &span class=&p&&{&/span&
&span class=&nb&&font-size&/span&&span class=&o&&:&/span& &span class=&m&&1&/span&&span class=&o&&.&/span&&span class=&m&&5&/span&&span class=&n&&rem&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&:any-link 伪类:&/h2&&p&允许你使用&code&:any-link&/code&伪类 &/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&nav&/span& &span class=&nd&&:any-link&/span& &span class=&p&&{&/span&
&span class=&nb&&background-color&/span&&span class=&o&&:&/span& &span class=&nb&&yellow&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&:matches 伪类:&/h2&&p&允许你使用&code&:matches&/code&伪类&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&p&/span&&span class=&nd&&:matches&/span&&span class=&o&&(&/span&&span class=&nd&&:first-child&/span&&span class=&o&&,&/span& &span class=&nc&&.special&/span&&span class=&o&&)&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&nb&&red&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&:not 伪类:&/h2&&p&允许你使用支持最多选择器的&code&:not&/code&伪类,将此降级为只选择一个选择器的&code&:not&/code& &/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&p&/span&&span class=&nd&&:not&/span&&span class=&o&&(&/span&&span class=&nd&&:first-child&/span&&span class=&o&&,&/span& &span class=&nc&&.special&/span&&span class=&o&&)&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&nb&&red&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&:: 伪元素语法降级:&/h2&&p&如果你的浏览器是旧浏览器,会将 :: 降级为 :。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&a&/span&&span class=&o&&:&/span&&span class=&nd&&:before&/span& &span class=&p&&{&/span&
&span class=&c&&/* ... */&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&overflow-wrap 属性:&/h2&&p&将&code&overflow-wrap&/code&转换为&code&word-wrap&/code&属性&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&body&/span& &span class=&p&&{&/span&
&span class=&nb&&overflow&/span&&span class=&o&&-&/span&&span class=&n&&wrap&/span&&span class=&o&&:&/span& &span class=&n&&break&/span&&span class=&o&&-&/span&&span class=&n&&word&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&不区分大小写的属性:&/h2&&p&允许你使用不区分大小写的属性&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&o&&[&/span&&span class=&nt&&frame&/span&&span class=&o&&=&/span&&span class=&nt&&hsides&/span& &span class=&nt&&i&/span&&span class=&o&&]&/span& &span class=&p&&{&/span&
&span class=&nb&&border-style&/span&&span class=&o&&:&/span& &span class=&nb&&solid&/span& &span class=&nb&&none&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&功能增强的 rga():&/h2&&p&允许你使用由空格分割的参数与可选的由斜线分割的不透明度新语法。&/p&&p&你也可以使用数字来表示颜色通道。&/p&&p&alpha 值接受百分比和数字,并且将 rgb() 作为可选参数。因此 rgb() 和 rgba() 现在是彼此的别名。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&div&/span& &span class=&p&&{&/span&
&span class=&nb&&background-color&/span&&span class=&o&&:&/span& &span class=&nb&&rgb&/span&&span class=&p&&(&/span&&span class=&m&&100&/span& &span class=&m&&222&/span&&span class=&o&&.&/span&&span class=&m&&2&/span& &span class=&m&&100&/span&&span class=&o&&.&/span&&span class=&m&&9&/span& &span class=&o&&/&/span& &span class=&m&&30%&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&p&功能增强的 hs1():&/p&&p&允许你使用由空格分割的参数与可选的由斜线分割的不透明度新语法。&/p&&p&hsl() 现在接受角度(deg, grad, rad, turn)以及用数字表示色调,用百分比或者数字来表示 alpha 值。所以 hsl() 与 hsla() 现在也是彼此的别名。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&div&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&n&&hsl&/span&&span class=&p&&(&/span&&span class=&m&&90&/span&&span class=&n&&deg&/span& &span class=&m&&90%&/span& &span class=&m&&70%&/span&&span class=&p&&);&/span&
&span class=&nb&&background-color&/span&&span class=&o&&:&/span& &span class=&n&&hsl&/span&&span class=&p&&(&/span&&span class=&m&&300&/span&&span class=&n&&grad&/span& &span class=&m&&25%&/span& &span class=&m&&15%&/span& &span class=&o&&/&/span& &span class=&m&&70%&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&&br&&/p&&h2&system-ui 字体:&/h2&&p&允许你使用 system-ui 通用字体系列。当前转换提供了一个实际的字体列表来作为降级方案。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&body&/span& &span class=&p&&{&/span&
&span class=&nb&&font-family&/span&&span class=&o&&:&/span& &span class=&n&&system&/span&&span class=&o&&-&/span&&span class=&n&&ui&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&hr&&h2&使用 cssnext 书写未来的 CSS&/h2&&p&cssnext 是一个 PostCSS 的包,我们可以在样式表中利用 cssnext 额外增加一些 CSS 规范。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&c&&/* custom properties */&/span&
&span class=&nd&&:root&/span& &span class=&p&&{&/span&
&span class=&o&&--&/span&&span class=&n&&heading&/span&&span class=&o&&-&/span&&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&m&&#ff0000&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&c&&/* custom selectors */&/span&
&span class=&k&&@custom-selector&/span& &span class=&nd&&:--headings&/span& &span class=&nt&&h1&/span&&span class=&o&&,&/span& &span class=&nt&&h2&/span&&span class=&o&&,&/span& &span class=&nt&&h3&/span&&span class=&o&&,&/span& &span class=&nt&&h4&/span&&span class=&o&&,&/span& &span class=&nt&&h5&/span&&span class=&o&&,&/span& &span class=&nt&&h6&/span&&span class=&p&&;&/span&
&span class=&c&&/* usage */&/span&
&span class=&nd&&:--headings&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&n&&var&/span&&span class=&p&&(&/span&&span class=&o&&--&/span&&span class=&n&&heading&/span&&span class=&o&&-&/span&&span class=&nb&&color&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&通过 cssnext,上述代码会被处理成以下内容&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&nt&&h1&/span&&span class=&o&&,&/span&
&span class=&nt&&h2&/span&&span class=&o&&,&/span&
&span class=&nt&&h3&/span&&span class=&o&&,&/span&
&span class=&nt&&h4&/span&&span class=&o&&,&/span&
&span class=&nt&&h5&/span&&span class=&o&&,&/span&
&span class=&nt&&h6&/span& &span class=&p&&{&/span&
&span class=&nb&&color&/span&&span class=&o&&:&/span& &span class=&m&&#ff0000&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&&p&这真的很简洁,其中还有很多令人兴奋的特性。因为我们书写的是未来规范的 CSS,所以 PostCSS 的生成步骤不需要浏览器去执行。&/p&&hr&&h2&用自定义函数扩展 CSS 的功能:&/h2&&p&使用 cssnext,我们可以通过 javascript 创建自定义函数来操作被解析的 CSS。在 Sass 中,我们经常使用生成行距的函数(根据基本的 line-height 计算),它有助于创建简单且可维护的垂直韵律。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&o&&$&/span&&span class=&nt&&line-height&/span&&span class=&o&&:&/span& &span class=&nt&&32px&/span&&span class=&o&&;&/span&
&span class=&c&&/* vertical rhythm function */&/span&
&span class=&k&&@function&/span& &span class=&nt&&vr&/span&&span class=&o&&($&/span&&span class=&nt&&amount&/span&&span class=&o&&)&/span& &span class=&p&&{&/span&
&span class=&k&&@return&/span& &span class=&o&&$&/span&&span class=&nt&&line-height&/span& &span class=&o&&*&/span& &span class=&o&&$&/span&&span class=&nt&&amount&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&c&&/* input */&/span&
&span class=&nc&&.selector&/span& &span class=&p&&{&/span& &span class=&nb&&margin-bottom&/span&&span class=&o&&:&/span& &span class=&n&&vr&/span&&span class=&p&&(&/span&&span class=&m&&2&/span&&span class=&p&&)&/span& &span class=&p&&}&/span&
&span class=&c&&/* output */&/span&
&span class=&nc&&.selector&/span& &span class=&p&&{&/span& &span class=&nb&&margin-bottom&/span&&span class=&o&&:&/span& &span class=&m&&64px&/span&&span class=&p&&;&/span& &span class=&p&&}&/span&
&/code&&/pre&&/div&&p&如果用 PostCSS 做的话,我们可以自定义 CSS 组件而不是函数。&/p&&div class=&highlight&&&pre&&code class=&language-css&&&span&&/span&&span class=&c&&/* input */&/span&
&span class=&nc&&.selector&/span& &span class=&p&&{&/span& &span class=&nb&&margin-bottom&/span&&span class=&o&&:&/span& &span class=&m&&2&/span&&span class=&n&&vr&/span& &span class=&p&&}&/span&
&span class=&c&&/* output */&/span&
&span class=&nc&&.selector&/span& &span class=&p&&{&/span& &span class=&nb&&margin-bottom&/span&&span class=&o&&:&/span& &span class=&m&&64px&/span&&span class=&p&&;&/span& &span class=&p&&}&/span&
&/code&&/pre&&/div&&hr&&h2&执行速度:&/h2&&p&PostCSS 声称比预处理器快 3-30 倍。这里使用 10000 个选择器的 5 个属性上使用上述 Sass 函数和 PostCSS 函数,也就是处理 50000 次,以下是对比结果。&/p&&p&Libsass 3.2&/p&&figure&&img src=&https://pic3.zhimg.com/v2-e35af0f7f21_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&365& data-rawheight=&50& class=&content_image& width=&365&&&/figure&&p&PostCSS&/p&&figure&&img src=&https://pic2.zhimg.com/v2-f8b8656ecc1fbc6afd6f_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&365& data-rawheight=&50& class=&content_image& width=&365&&&/figure&&p&&br&&/p&&p&从结果中很显然看出,PostCSS 比 LibSass 的速度快了很多。&/p&&hr&&p&原文链接:&a href=&https://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s%3F__biz%3DMzI4Mzc5NDk4MA%3D%3D%26mid%3D%26idx%3D1%26sn%3D4e8c8dc4c089b%26chksm%3Deb84090bdcfb3b3abfb0e4ea5ef48e0b01f170a4ed773%26scene%3D38%23wechat_redirect& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LeetCode 微信公众号&/a&&/p&
PostCSS 是使用 javascript 插件转换 CSS 的后处理器。PostCSS 本身不会对你的 CSS 做任何事情,你需要安装一些 plugins 才能开始工作。这不仅使其模块化,同时功能加强。cssnext 是一个 CSS transpiler,允许你使用最新的 CSS 语法。cssnext 把新 CSS 规范…
&figure&&img src=&https://pic4.zhimg.com/v2-f17ef4f6b756143cbfea192a0b7c04db_b.jpg& data-rawwidth=&1280& data-rawheight=&705& class=&origin_image zh-lightbox-thumb& width=&1280& data-original=&https://pic4.zhimg.com/v2-f17ef4f6b756143cbfea192a0b7c04db_r.jpg&&&/figure&&blockquote&&b&关键字:&/b&Tensorflow,JavaScript,AI,前端开发,人工智能,神经网络,遗传算法&/blockquote&&a class=&video-box& href=&https://link.zhihu.com/?target=https%3A//www.zhihu.com/video/785664& target=&_blank& data-video-id=&& data-video-playable=&true& data-name=&& data-poster=&https://pic4.zhimg.com/80/v2-d1f78f128e23c55a3ab7f_b.jpg& data-lens-id=&785664&&
&img class=&thumbnail& src=&https://pic4.zhimg.com/80/v2-d1f78f128e23c55a3ab7f_b.jpg&&&span class=&content&&
&span class=&title&&&span class=&z-ico-extern-gray&&&/span&&span class=&z-ico-extern-blue&&&/span&&/span&
&span class=&url&&&span class=&z-ico-video&&&/span&https://www.zhihu.com/video/785664&/span&
&hr&&h2&&b&先上最终效果&/b&&/h2&&p&T-Rex Runner 是隐藏在 Chrome 中的彩蛋游戏,最近我用刚推出的 &a href=&https://link.zhihu.com/?target=https%3A//js.tensorflow.org/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TensorFlow.js&/a& 开发了一个完全独立运行于浏览器环境下的 AI 程序,如下图所示 AI 可以轻松控制暴龙(T-Rex)避开障碍物。&/p&&figure&&img src=&https://pic1.zhimg.com/v2-869af0c3cbc27_b.jpg& data-size=&normal& data-rawwidth=&620& data-rawheight=&200& data-thumbnail=&https://pic1.zhimg.com/v2-869af0c3cbc27_b.jpg& class=&origin_image zh-lightbox-thumb& width=&620& data-original=&https://pic1.zhimg.com/v2-869af0c3cbc27_r.jpg&&&figcaption&AI 在尝试 3 次后逐渐学会了如何控制暴龙避让障碍物&/figcaption&&/figure&&p&&br&&/p&&figure&&img src=&https://pic2.zhimg.com/v2-350b940f4ca3c4a2e3cb_b.jpg& data-size=&normal& data-rawwidth=&620& data-rawheight=&200& data-thumbnail=&https://pic2.zhimg.com/v2-350b940f4ca3c4a2e3cb_b.jpg& class=&origin_image zh-lightbox-thumb& width=&620& data-original=&https://pic2.zhimg.com/v2-350b940f4ca3c4a2e3cb_r.jpg&&&figcaption&引入遗传算法后,尝试 2 次后 AI 即可学会控制&/figcaption&&/figure&&p&&br&&/p&&p&&b&查看在线演示&/b&&/p&&ul&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//magiccube.github.io/tensorflow-rex-run/neural-network.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&神经网络版&/a&&/b& - 仅支持 Chrome 桌面版&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//magiccube.github.io/tensorflow-rex-run/genetic-neural-network.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&遗传算法 + 神经网络&/a&&/b& - 仅支持 Chrome 桌面版&/li&&/ul&&p&&b&下载或收藏我在 Github 上的源代码&/b&&/p&&ul&&li&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&MagicCube/t-rex-run&/a&&/li&&/ul&&p&&br&&/p&&hr&&h2&&b&概述&/b&&/h2&&h2&关于 T-Rex Runner 彩蛋游戏&/h2&&p&作为 Chrome 浏览器死忠,你或许早已发现隐藏在 Chrome 浏览器“无法连接到互联网”报错页面中的彩蛋“T-Rex Runner”游戏。&/p&&figure&&img src=&https://pic3.zhimg.com/v2-f5ffee22de6c37d4cb8f1_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&720& data-rawheight=&479& class=&origin_image zh-lightbox-thumb& width=&720& data-original=&https://pic3.zhimg.com/v2-f5ffee22de6c37d4cb8f1_r.jpg&&&/figure&&p&如果你还没有玩儿过 T-Rex Runner,可以按照下面几个步骤开启彩蛋:&/p&&ol&&li&打开 Chrome 浏览器,在地址栏输入 chrome://dino,然后回车;&/li&&li&你将会看到上面的报错界面,但是还处于静止状态,不要怕这就是彩蛋的入口;&/li&&li&敲击空格键,开始游戏吧!&/li&&/ol&&p&你的任务就是在不碰到仙人掌和空中的翼龙的情况下保持前行,坚持的时间越久则分数越高,难度也随之越来越大。&/p&&p&&br&&/p&&h2&关于 TensorFlow.js&/h2&&figure&&img src=&https://pic4.zhimg.com/v2-2dfbfbd7aca8ccf9dabeb36_b.jpg& data-caption=&& data-size=&small& data-rawwidth=&709& data-rawheight=&143& class=&origin_image zh-lightbox-thumb& width=&709& data-original=&https://pic4.zhimg.com/v2-2dfbfbd7aca8ccf9dabeb36_r.jpg&&&/figure&&p&作为深度学习界的当红炸子鸡——TensorFlow 开源组织终于在 2018 年 3 月推出了首个 &a href=&https://link.zhihu.com/?target=https%3A//github.com/tensorflow/tfjs& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&JavaScript 版本&/a&。TensorFlow.js 可以在浏览器端完成模型训练、执行和再训练等基本任务,并且借助 WebGL 技术,可以和 Python、C++ 版本一样能够通过 GPU 硬件加速完成计算过程。&/p&&p&目前网上关于 TensorFlow.js 的教程寥寥无几,基本上就是官方示例的解析,本文希望能从实例出发,给大家补充一些学习的动力!&/p&&p&&br&&/p&&h2&关于本文&/h2&&p&本文的目标是基于 TensorFlow.js 在浏览器端构建人工神经网络,通过反复训练让 AI 学会如何控制暴龙成功避开障碍物。本文的结构如下:&/p&&ol&&li&&b&改造游戏程序&/b&:介绍游戏核心代码逻辑,用 ES6 等技术栈重构游戏代码,并引入全新的游戏生命周期事件。&/li&&li&&b&实现算法模型&/b&:重点介绍如何实现基于人工神经网络的 AI 算法模型。&/li&&li&&b&集成算法模型&/b&:将算法模型与游戏进行集成。&/li&&li&&b&优化算法模型&/b&:通过增加 AI 玩家和暴龙的个数,我们无需改动算法模型,即可轻松提升机器学习效率。&/li&&li&&b&总结&/b&&/li&&/ol&&p&&br&&/p&&hr&&h2&&b&1. 改造游戏程序&/b&&/h2&&h2&1.1 用现代化前端技术栈重构&/h2&&p&T-Rex Runner 的源代码可以在 &a href=&https://link.zhihu.com/?target=https%3A//cs.chromium.org/chromium/src/components/neterror/resources/offline.js%3Fq%3Dt-rex%2Bpackage%3A%255Echromium%2524%26dr%3DC%26l%3D7& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Chromium 的代码仓库&/a&中找到,但是这个小游戏是在 2014 年编写的,使用的都是 ES5 时代的技术,更糟糕的是由于缺少模块化,整个游戏的源代码都放在&a href=&https://link.zhihu.com/?target=https%3A//cs.chromium.org/chromium/src/components/neterror/resources/offline.js%3Fq%3Dt-rex%2Bpackage%3A%255Echromium%2524%26dr%3DC%26l%3D7& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&同一个文件中&/a&,这很大程度上增加了理解和修改源代码的难度。&/p&&p&因此,我先花了一个下午的时间,用 ES6/ES7 + LESS + Webpack 等现代化前端技术栈重写了 t-rex-runner 项目,并且引入 ESLint 来保障代码质量。&/p&&p&除此外,我还移除了声效、鼠标控制、移动端支持和 GameOver 画面等相关代码,并且为了后面运用遗传算法,我还为游戏加入了多人模式(Multiplayer Mode,即游戏中同一局,有多只暴龙同时出现)。&/p&&p&有关代码已上传至 &a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Github&/a&,详细请见 &a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/tree/master/src/game& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&src/game&/a& 目录中。&/p&&p&&br&&/p&&h2&1.2 游戏核心代码&/h2&&p&t-rex-runner 是一个非常标准的面向对象编程游戏程序,事实上你也可以将它作为 HTML5 游戏开发入门的经典示例。重构后的 t-rex-runner 项目,主要包含以下类型:&/p&&figure&&img src=&https://pic4.zhimg.com/v2-dba1d1ae59e80_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&1141& data-rawheight=&701& class=&origin_image zh-lightbox-thumb& width=&1141& data-original=&https://pic4.zhimg.com/v2-dba1d1ae59e80_r.jpg&&&/figure&&ul&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/Runner.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Runner 类&/a&&/b&:这是游戏的核心,掌管整个游戏的生命周期,主要类成员包括:&/li&&ul&&li&&b&currentSpeed 属性&/b&:表示当前游戏速度,玩家坚持的时间越长速度就越快,速度越快难度越高。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/3dced0eebee53dd4cd0a9b3c281b03cd/src/game/Runner.js%23L130& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&init() 方法&/a&&/b&:负责根据 config 参数初始化 &code&Canvas&/code&、&code&Horizon&/code&、&code&DistanceMeter&/code&、&code&TRexGroup&/code& 等类的实例,并且首次触发 &code&restart()&/code& 和 &code&update()&/code& 。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/3dced0eebee53dd4cd0a9b3c281b03cd/src/game/Runner.js%23L442& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&restart() 方法&/a&&/b&:重置所有运行时参数,重新启动全新一局游戏。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/3dced0eebee53dd4cd0a9b3c281b03cd/src/game/Runner.js%23L264& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&update() 方法&/a&&/b&:刷新并重绘当前帧,通过 &code&requestAnimationFrame()&/code& 调用,大约为 60 帧每秒(由 &a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/RuntimeConfig.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Runtime.getFPS()&/a& 方法决定)。&/li&&/ul&&/ul&&p&&br&&/p&&ul&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/Trex.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Trex 类&/a&&/b&:代表一只 T-Rex,即暴龙,主要类成员包括:&/li&&ul&&li&&b&jumping 属性&/b&:表示当前暴龙是否已经处于跳跃状态(跳起、跳跃中或落地中等均为 &code&true&/code&)。&/li&&li&&b&reset() 方法&/b&:重置暴龙的所有参数,由 &code&Runner.restart()&/code& 在游戏重启前调用&/li&&li&&b&startJump() 方法&/b&:控制暴龙起跳,用于躲避仙人掌。&/li&&li&&b&setDuck() 方法&/b&:控制暴龙匍匐前进,用于躲避低空飞行的翼龙。&/li&&/ul&&/ul&&p&&br&&/p&&ul&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/TrexGroup.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&TrexGroup 类&/a&&/b&:代表包含 n 个暴龙的种群,这在原先代码中是没有的,之所以要有种群的概念是为了支持多玩家模式,即同时有 n 只暴龙以各自独立的方式玩同一局游戏。除拥支持 Trex 类大多数方法外,还包括:&/li&&ul&&li&&b&lives() 方法&/b&:获取当前种群中活着的暴龙数量。&/li&&/ul&&/ul&&p&&br&&/p&&ul&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/Obstacle.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Obstacle 类&/a&&/b&:代表障碍物,例如各种高度、宽度的仙人掌和空中的翼龙等,主要类成员包括:&/li&&ul&&li&type 属性:表示当前障碍物类型,包括仙人掌(CACTUS_SMALL / CACTUS_LARGE)和翼龙(PTERODACTYL)等。&/li&&li&width 和 height 属性:表示障碍物的大小。&/li&&li&xPos 和 yPos 属性:表示障碍物的位置。&/li&&/ul&&/ul&&p&&br&&/p&&p&除以上核心类型外,其他还包括:&/p&&ul&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/Horizon.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Horizon 类&/a&&/b&:代表整个游戏舞台背景或称场景,熟悉游戏开发的同学一定知道它类似于很多框架中 stage / scene / background 概念,在本游戏中包含云、星星、月亮和最重要的障碍物 Obstacles。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/HorizonLine.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&HorizonLine 类&/a&&/b&:代表地平线,坑洼不平的路面有助于人推到出当前“速度”。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/CollisionBox.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CollisionBox 类&/a&&/b&:代表一个矩形,通常一个 Trex 或 Obstacle 可以用若干个矩形组成一个近似多边形,用于计算多边形碰撞。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/Cloud.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Cloud 类&/a&&/b&:代表云朵,这是为了将来做计算机图像识别时,做干扰项用。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/DistanceMeter.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&DistanceMeter 类&/a&:&/b&代表右上角的距离仪表。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/ImageSprite.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ImageSprite 模块&/a&&/b&:经典的 Sprite 贴图。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/constants.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&constants 模块&/a&&/b&:用于存储游戏的默认配置参数。&/li&&li&&b&&a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/game/utils.js& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&utils 模块&/a&&/b&:包含了常用的工具方法。&/li&&/ul&&p&&br&&/p&&h2&1.3 提供生命周期事件&/h2&&p&为了让 AI 替代人类参与到游戏中,我们除了需要有 Trex.startJump() 这样的输出类方法外,还需在 Runner 类中提供必要的事件作为输入:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-ac5577f84eabd7c0912c92ebaddc0095_b.jpg& data-caption=&& data-size=&normal& data-rawwidth=&646& data-rawheight=&816& class=&origin_image zh-lightbox-thumb& width=&646& data-original=&https://pic3.zhimg.com/v2-ac5577f84eabd7c0912c92ebaddc0095_r.jpg&&&/figure&&ul&&li&&b&onReset() 事件&/b&:当游戏重启时将触发该事件,通常 AI 模型的训练的过程将在此事件中完成。&/li&&li&&b&onRunning() 事件&/b&:每只没有“crash”的暴龙会在每一次 &code&update()&/code& 后触发该事件,事件的返回值将被作为 &code&action&/code&,当 &code&action&/code& 为 &code&1&/code& 时表示将执行跳跃,&code&0&/code& 则表示保持不变。 可以利用该事件实现对游戏状态的监控,同时命令暴龙在特定的时机改变跳跃状态。&/li&&li&&b&onCrash() 事件&/b&:当暴龙撞到仙人掌或者翼龙的时候,将触发该事件,可以通过该事件评价 AI 模型执行的效果,例如在遗传算法中,可以用它来计算种群中某一暴龙模型的排名。&/li&&/ul&&p&下面是一个示例程序,基于以上生命周期事件:&/p&&div class=&highlight&&&pre&&code class=&language-js&&&span&&/span&&span class=&kd&&let&/span& &span class=&nx&&runner&/span& &span class=&o&&=&/span& &span class=&kc&&null&/span&&span class=&p&&;&/span&
&span class=&c1&&// 排名&/span&
&span class=&kd&&let&/span& &span class=&nx&&rankList&/span& &span class=&o&&=&/span& &span class=&p&&[];&/span&
&span class=&c1&&// 初始化游戏。&/span&
&span class=&kd&&function&/span& &span class=&nx&&setup&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&c1&&// 创建游戏运行时&/span&
&span class=&nx&&runner&/span& &span class=&o&&=&/span& &span class=&k&&new&/span& &span class=&nx&&Runner&/span&&span class=&p&&(&/span&
&span class=&s1&&'.game'&/span&&span class=&p&&,&/span&
&span class=&c1&&// HTML 中对应的游戏 DIV 容器&/span&
&span class=&p&&{&/span&
&span class=&nx&&T_REX_COUNT&/span&&span class=&o&&:&/span& &span class=&mi&&10&/span&&span class=&p&&,&/span&
&span class=&c1&&// 每一局同时有 10 只暴龙&/span&
&span class=&nx&&onReset&/span&&span class=&o&&:&/span& &span class=&nx&&handleReset&/span&&span class=&p&&,&/span&
&span class=&nx&&onRunning&/span&&span class=&o&&:&/span& &span class=&nx&&handleRunning&/span&&span class=&p&&,&/span&
&span class=&nx&&onCrash&/span&&span class=&o&&:&/span& &span class=&nx&&handleCrash&/span&
&span class=&p&&}&/span&
&span class=&p&&);&/span&
&span class=&c1&&// 初始化&/span&
&span class=&nx&&runner&/span&&span class=&p&&.&/span&&span class=&nx&&init&/span&&span class=&p&&();&/span&
&span class=&p&&}&/span&
&span class=&kd&&let&/span& &span class=&nx&&firstTime&/span& &span class=&o&&=&/span& &span class=&kc&&true&/span&&span class=&p&&;&/span&
&span class=&c1&&// 每次游戏重新开始前会调用此方法。&/span&
&span class=&c1&&// tRexes 参数表示当前的暴龙种群。&/span&
&span class=&kd&&function&/span& &span class=&nx&&handleReset&/span&&span class=&p&&({&/span& &span class=&nx&&tRexes&/span& &span class=&p&&})&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&firstTime&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&nx&&firstTime&/span& &span class=&o&&=&/span& &span class=&kc&&false&/span&&span class=&p&&;&/span&
&span class=&nx&&tRexes&/span&&span class=&p&&.&/span&&span class=&nx&&forEach&/span&&span class=&p&&((&/span&&span class=&nx&&tRex&/span&&span class=&p&&)&/span& &span class=&o&&=&&/span& &span class=&p&&{&/span&
&span class=&c1&&// 随机初始化每一只暴龙的模型&/span&
&span class=&c1&&// minDistance 在本例中代表可容忍的障碍物最小间距&/span&
&span class=&nx&&tRex&/span&&span class=&p&&.&/span&&span class=&nx&&model&/span& &span class=&o&&=&/span& &span class=&p&&{&/span& &span class=&nx&&minDistance&/span&&span class=&o&&:&/span& &span class=&nb&&Math&/span&&span class=&p&&.&/span&&span class=&nx&&random&/span&&span class=&p&&()&/span& &span class=&o&&*&/span& &span class=&mi&&50&/span& &span class=&p&&};&/span&
&span class=&p&&});&/span&
&span class=&p&&}&/span& &span class=&k&&else&/span& &span class=&p&&{&/span&
&span class=&c1&&// 打印排名&/span&
&span class=&nx&&rankList&/span&&span class=&p&&.&/span&&span class=&nx&&forEach&/span&&span class=&p&&(&/span&
&span class=&p&&(&/span&&span class=&nx&&tRex&/span&&span class=&p&&,&/span& &span class=&nx&&i&/span&&span class=&p&&)&/span& &span class=&o&&=&&/span& &span class=&nx&&console&/span&&span class=&p&&.&/span&&span class=&nx&&info&/span&&span class=&p&&(&/span&&span class=&nx&&i&/span& &span class=&o&&+&/span& &span class=&mi&&1&/span&&span class=&p&&,&/span& &span class=&nx&&tRex&/span&&span class=&p&&.&/span&&span class=&nx&&model&/span&&span class=&p&&.&/span&&span class=&nx&&minDistance&/span&&span class=&p&&)&/span&
&span class=&p&&);&/span&
&span class=&c1&&// 清空排名&/span&
&span class=&nx&&rankList&/span&&span class=&p&&.&/span&&span class=&nx&&splice&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&c1&&// 在游戏运行中,活着的暴龙会持续调用此方法来询问是否要跳跃。&/span&
&span class=&c1&&// tRex 参数表示当前上下文中的暴龙。&/span&
&span class=&c1&&// state 参数中,obstacleX 表示距离最近的障碍物的横坐标,obstacleWidth&/span&
&span class=&c1&&// 表示障碍物宽度,speed 表示当前游戏全局速度。&/span&
&span class=&c1&&// 方法返回 1 表示跳跃,2 则表示不变。&/span&
&span class=&kd&&function&/span& &span class=&nx&&handleRunning&/span&&span class=&p&&({&/span& &span class=&nx&&tRex&/span&&span class=&p&&,&/span& &span class=&nx&&state&/span& &span class=&p&&})&/span& &span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&nx&&state&/span&&span class=&p&&.&/span&&span class=&nx&&obstacleX&/span& &span class=&o&&&=&/span& &span class=&nx&&tRex&/span&&span class=&p&&.&/span&&span class=&nx&&model&/span&&span class=&p&&.&/span&&span class=&nx&&minDistance&/span& &span class=&o&&&&&/span&
&span class=&o&&!&/span&&span class=&nx&&tRex&/span&&span class=&p&&.&/span&&span class=&nx&&jumping&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&c1&&// 这里我们直接用一个“人工【的】智能”,即:&/span&
&span class=&c1&&// 当前障碍物距离到达阈值,则命令暴龙跳跃&/span&
&span class=&k&&return&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&k&&return&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&kr&&const&/span& &span class=&nx&&deadTrexes&/span& &span class=&o&&=&/span& &span class=&p&&[];&/span&
&span class=&c1&&// 当暴龙“crash”时,会调用此方法来通知。&/span&
&span class=&kd&&function&/span& &span class=&nx&&handleCrash&/span&&span class=&p&&({&/span& &span class=&nx&&tRex&/span& &span class=&p&&})&/span& &span class=&p&&{&/span&
&span class=&c1&&// 记录排名,最后 crashed 暴龙排在最前面&/span&
&span class=&nx&&rankList&/span&&span class=&p&&.&/span&&span class=&nx&&unshift&/span&&span class=&p&&(&/span&&span class=&nx&&tRex&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&c1&&// 订购 DOMContentLoaded 事件以触发 setup() 方法&/span&
&span class=&nb&&document&/span&&span class=&p&&.&/span&&span class=&nx&&addEventListener&/span&&span class=&p&&(&/span&&span class=&s1&&'DOMContentLoaded'&/span&&span class=&p&&,&/span& &span class=&nx&&setup&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&p&&br&&/p&&hr&&h2&&b&2. 实现算法模型&/b&&/h2&&h2&2.1 初中生都能懂的算法模型&/h2&&p&“算法模型”一词对于刚接触 AI 的前端同学来说,可能听上去有些高不可测,其实不然,让我们先合上教科书,来一起看看下面这个初中就学过的简单公式:&/p&&figure&&img src=&https://pic3.zhimg.com/v2-4e58aeea05bab22c544da_b.jpg& data-size=&normal& data-rawwidth=&299& data-rawheight=&120& class=&content_image& width=&299&&&figcaption&据统计每多一个公式,就会少 n 个读者,这是本文的倒数第 3 个公式&/figcaption&&/figure&&p&公式中,&code&x&/code& 是一&b&输入项(inputs)&/b& ,y 是&b&输出项(outputs)&/b&,而 &code&f(x)&/code& 就是&b&模型 (model)&/b&的核心函数&b&。例如:&/b&&/p&&ul&&li&当 &img src=&https://www.zhihu.com/equation?tex=y+%3D+weight+%5Ccdot+x+%2B+bias& alt=&y = weight \cdot x + bias& eeimg=&1&& 时,因为是&b&线性函数(Linear Function,也称一次方程)&/b&,所以被称为&b&线性模型(Linear Model)&/b&,该模型除了函数公式外,还包含了 &code&weight&/code&、&code&bias&/code& 等参数,举一个例子,据说知乎文章中美多一个公式,就会少 n 个读者,这就是一个典型的线性模型&b&;&/b&&/li&&/ul&&p&&br&&/p&&p&事实上 AI 决定当前是否需要跳跃也是一个线性模型,用一个线性函数表示就是:&/p&&p&&img src=&https://www.zhihu.com/equation?tex=y+%3D+w1+%2A+obstacleX+%2B+w2+%2A+obstacleWidth+%2B+b& alt=&y = w1 * obstacleX + w2 * obstacleWidth + b& eeimg=&1&&&/p&&blockquote&&code&obstacleX&/code& 和 &code&obstacleWidth&/code& 是输入项,它们来自于 &code&handleRunning()&/code& 方法的 &code&state&/code& 参数,该参数中:&br&
- &code&obstacleX&/code& 表示距离最近的障碍物的横坐标&br&
- &code&obstacleWidth&/code& 表示障碍物宽度&br&
- &code&speed&/code& 表示当前游戏全局速度。&br&&br&当 &code&y&/code& 输出的值小于 &code&0&/code& 时,则表示需要“跳跃”。&/blockquote&&p&&br&&/p&&p&其中 &code&w1&/code&、&code&w2&/code& 分别表示 &code&obstacleX&/code& 和 &code&obstacleWidth&/code& 的&b&权重(weight)&/b&, &code&b&/code& 是&b&偏移量(bias)&/b&,它们都是该线性模型的参数。&/p&&p&与初中数学有所不同的是,这里的输入和输出通常都是&b&向量(vector)&/b&,而不像前面的例子中都是标量&b&,&/b&并且多为线性运算。千万不要被线性数学和公式吓跑,“算法”不完全是“数学”,更不是“算数”,请接着往下看。&/p&&p&&br&&/p&&h2&2.2 预测,训练和评价&/h2&&p&&b&预测 Prediction&/b&&/p&&p&在机器学习中,已知输入项 &code&x&/code& 和模型求 &code&y&/code& 时,被称为&b&预测(predict)&/b&过程。&/p&&p&&br&&/p&&p&&b&训练 Training&/b&&/p&&p&通过已知输入项 &code&x&/code& 和输出项 &code&y&/code& 来调节模型中 &code&w1&/code&、&code&w2&/code& 和 &code&b&/code& 参数直到“最佳效果”的过程,被称为&b&训练(train)&/b&过程,而 &code&y&/code& 因为是已知的输出项,又被称为&b&标签(label)&/b&,多组&code&x&/code& 和 &code&y&/code& 在一起被称为&b&训练数据集(training data set)。&/b&训练通常需要反复执行很多次,才能达到“最佳效果”。&/p&&p&&br&&/p&&p&&b&评价 Evaluation&/b&&/p&&p&在训练过程中,将训练数据集中的 &code&x&/code&
作为输入项,执行预测过程,将预测结果与标签 &code&y&/code& 的实际结果进行对比,并通过一个函数得到一个分值用以表示当前模型的拟合能力,被称为&b&评价(evaluatie)&/b&过程,这个函数被称为评价函数或&b&损失函数(loss function)&/b&。&/p&&p&&br&&/p&&p&&b&机器学习就是一个不断训练、评价迭代的模型训练过程,训练得越好,则未来预测得越准确。&/b&&/p&&p&&br&&/p&&blockquote&2.1 和 2.2 这两节中的内容均为笔者自己多年工作实践的总结,与教科书难免有差异还请谅解,有关术语定义请以教科书为准。&/blockquote&&p&&br&&/p&&h2&2.3 定义算法模型抽象类&/h2&&p&在正式进入到 AI 算法实现环节之前,我们还需要定义一个通用的面向对象 AI 模型—— &a href=&https://link.zhihu.com/?target=https%3A//github.com/MagicCube/t-rex-run/blob/master/src/ai/models/Model.js& class=& wrap

我要回帖

更多关于 oppo账号密码怎么找回 的文章

 

随机推荐