众所周知Rust的学习曲线极为陡峭,学习过程中挫败感极强,像笔者这样有十几年开发经验的人也要经常需要好几天时间才能长度搞清楚一个小小的细节问题,具体可以参见前文《从内存布局上看,Rust的胖指针到底胖在栈上还是胖在堆上》。因此在学习掌握Rust的过程中还是需要一些没那么硬核的知识点进行穿插、点缀的。
Nicolas Frankel一直是我非常关注的Rust技术专栏作者之一,近期我看到他的一篇有关于Rust与JS结合搭建Serverless WebAssembly的文章,立刻感觉眼前一亮,这篇文章当中没有那些繁锁的权限传递机制、智能指针等项目,只要跟着作者的代码样例进行模仿就行了,而且这方面的知识也比较实用,不失为一篇在学习中途中可以放松一下转换心情的好文章,下面就带大家奇文共赏。
我们知道JavaScript是前端方面唯一个算得上是通用的语言,各种前端流行框架本质上都是基于JavaScript。虽然为前端生的JavaScript存在很多储如性能、并发等方面的先天不足,但是也应该看到JavaScript 开发者社群还在大幅增长,围绕前端 JavaScript 的生态也是日益繁荣,而且前端技术变化很快,几年前还称霸一时的Flash几乎直线坠落,完全被H5干掉,从NodeJS、DENO到Vue.js,各种新框架也是不断涌现,也让大家应接不暇,可以说JS体系的繁荣是有目共睹的。
虽然有关语言优劣的争论大多是没有作何实际意义的,但不可否认的是JavaScript往往处在编程语言鄙视链的底端,很多程序员都认为JS之所以能幸存下来,是因为它将执行脚本代码的责任从服务器转移到客户端,这样就减轻了服务器上的很大压力。不过相对而言,客户端的压力却因此大大增加了,想提升上网体验前端程序员几乎只能建议用户去购买功能更强大而且价格昂贵的手机、PAD或者PC。而想要优化JavaScript 引擎似乎还得靠Rust才能做到。在介绍下面的方案之前,我们先来认识一下WebAssembly。
WebAssembly(缩写为 Wasm)是一种用于基于堆栈的虚拟机的二进制指令格式。Wasm 被设计为编程语言的可移植编译目标,支持在 Web 上部署客户端和服务器应用程序。
总得来说Wasm并非要取代JavaScript,而是指在提高前后端交互的整体性能。尽管Rust多用于后端,但它的特性确实有助于提升WebAssembly的编译、启动及运行速度,下面我们就一起来感受一下Rust+Wasm的强大威力。
我们第一个步骤侧重于让大家了解设置方法,这是一个Ctrl+C、Ctrl+V式复制粘贴项目。这个项目利用一个高效的Cargo 插件cargo-generate来提升项目管理效率,它允许使用现有的 Git 存储库作为模板来创建新项目。在本例中,模板是一个待编译的 Wasm Rust项目。具体项目的树形结构如下:
这是非常典型的Rust项目结构。现在我们来看一下Cargo.toml文件。
[package]
name = "wasm-game-of-life"
version = "0.1.0"
authors = ["Nicolas Frankel <nicolas@frankel.ch>"]
edition = "2018"
[lib]
crate-type = ["cdylib", "rlib"]
[features]
default = ["console_error_panic_hook"]
[dependencies]
wasm-bindgen = "0.2.63"
# Rest of the file omitted for clarity purposes
这里Cargo.toml其实发挥了前端项目中pom.xml的作用,这里列出有关包、依赖项、编译提示等的元信息,并定义与Wasm的依赖关系。当然截止目前这个项目还不是很有趣,不过我们会慢慢来建立一个项目,使Wasm的Rust代码能够高效交互。
接下来让运行命令:
npm init wasm-app www
你会看到以下输出结构:
wasm-game-of-life/
└── www/
├── package.json
├── webpack.config.js
├── index.js
├── bootstrap.js
└── index.html
其中webpack.config.js是调用 Wasm 代码的入口点,index.js是异步加载器包装器。进行完上述步骤后,接下来只要我们完成以下四步,就可以执行整个Wasm代码链。
将 Rust 代码编译为 Wasm
生成 JavaScript 适配器代码
安装NPM 依赖项 npm install
执行npm run start
浏览到http://localhost:8080会显示一条简单的alert()消息。
在带着广大读者们重新做一遍教程之前,笔者这里先给出一些有意义的结论。也就是Wsam+Rust的结合过程中,可以归结为以下三步:
从 JavaScript 调用 Rust
从 Rust 调用 JavaScript
从 Rust 调用浏览器 API
好接下来我们就一点一点学习这些步骤,要从 JavaScript 调用 Rust,需要将 Rust 代码编译为 Wasm 并提供瘦 JavaScript 包装器。在Rust方面具体方案如下:
pub fn foo() {
// do something
}
在 JavaScript 代码方面示例如下:
import * as wasm from "hello-wasm-pack";
wasm.foo();
将hello-wasm-pack包中的所有内容导入wasm命名空间之后,用户就可以调用foo()函数了。
从 Rust 调用 JavaScript
Rust 调用 JavaScript 函数时需要通过extern关键字声明使用外部函数接口,具体如下:
extern "C" {
fn random() -> f64;
}
fn random_boolean() -> bool {
random() < 0.5
}
注意虽然这里关键字是extern "C",但这并不是 C 代码,Rust中这就是正确的语法,因此我们只要用它就可以了。接下来需要进行有关js沙箱(js-sys crate)的设置工作,如果要详细了解相关内容,可以参考以下链接:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
接下来需要将js-sys添加到cargo.toml当中,具体如下::
Cargo.toml
[dependencies]
js-sys = { version = "0.3.50", optional = true }
[features]
default = ["js-sys"]
上述配置将允许以下代码在js沙箱中使用:
use js_sys::Math;
#[wasm_bindgen]
fn random_boolean() -> bool {
Math::random() < 0.5
}
上述代码中的Math.random()语句会在在运行时实现由rust调JavaScript的目标。
当然只是调用JavaScript还是不够的,因为很多客户端API,如console.log(),需要调用浏览器API。
下面是配置方案:
Cargo.toml
[dependencies]
web-sys = { version = "0.3", features = ["console"] }
配置完成后我们就可以通过以下样例来调用浏览器API:
wasm.rs
extern crate web_sys;
:console; :
#[wasm_bindgen]
impl Foo {
pub fn new() -> Foo {
utils::set_panic_hook();
Universe {}
}
pub fn log(&self) {
console::log_1("Hello from console".into());
}
}
我们在重复一下之前的要点,在前端使用Rust 的三大要决分别是:从 JavaScript 调用 Rust,从 Rust 调用 JavaScript,从 Rust 调用浏览器 API。
原文地址:https://blog.frankel.ch/start-rust/5/
源码地址:https://github.com/ajavageek/rust-game-of-life
声明:本文由CSDN翻译,转载请注明来源。
当涉及屏幕适配方案时,我们常常被众多选择所困扰,如postcss-pxtorem、postcss-px2rem、px2rem-loader、postcss-plugin-px2rem等。然而,在实际测试中,由于不同的Vue和Webpack版本,很多这些方式已经无法使用,反而带来了更多麻烦。
为了尽快解决问题,我们应该始终以解决问题为导向,首先采用那些已经获得验证并能产生效果的方法。对于上述列举的方案,虽然没有一一测试过,但我们需要明确的是,抓住解决问题的关键。
针对移动端和PC端适配,我建议将两者进行拆分并进行工程化配置,以避免整体框架调整后在某些页面上出现轻微不协调。在某些情况下,你可能会注意到笔记本电脑上显示比例缩放后的细微差异,这可以通过插入【整体缩放自适应解决方案(阿里团队高清方案)的JS代码】来解决。
viewport即视窗、视口,用于显示网页部分的区域,在PC端视口即是浏览器窗口区域,在移动端,为了让页面展示更多的内容,视窗的宽度默认不为设备的宽度,在移动端视窗有三个概念:布局视窗、视觉视窗、理想视窗。
viewport详细设置:
移动端默认会缩放大尺寸的页面的,当我们把上述代码去掉之后,就会随着移动端缩放的比例走,而且还可以自由放大。
方案统计:
代码原理:
// 仅在移动端时候生效,或者浏览器手机模式
// 整体缩放自适应解决方案(阿里团队高清方案) 淘宝m端使用的解决方案
! function (e) {
function t(a) {
if (i[a]) return i[a].exports;
var n = i[a] = {
exports: {},
id: a,
loaded: !1
};
return e[a].call(n.exports, n, n.exports, t), n.loaded = !0, n.exports
}
var i = {};
return t.m = e, t.c = i, t.p = "", t(0)
}([function (e, t) {
"use strict";
Object.defineProperty(t, "__esModule", {
value: !0
});
var i = window;
t["default"] = i.flex = function (e, t) {
var a = e || 100,
n = t || 1,
r = i.document,
o = navigator.userAgent,
d = o.match(/Android[\S\s]+AppleWebkit/(\d{3})/i),
l = o.match(/U3/((\d+|.){5,})/i),
c = l && parseInt(l[1].split(".").join(""), 10) >= 80,
p = navigator.appVersion.match(/(iphone|ipad|ipod)/gi),
s = i.devicePixelRatio || 1;
p || d && d[1] > 534 || c || (s = 1);
var u = 1 / s,
m = r.querySelector('meta[name="viewport"]');
m || (m = r.createElement("meta"), m.setAttribute("name", "viewport"), r.head.appendChild(m)), m
.setAttribute("content", "width=device-width,user-scalable=no,initial-scale=" + u + ",maximum-scale=" +
u + ",minimum-scale=" + u), r.documentElement.style.fontSize = a / 2 * s * n + "px"
}, e.exports = t["default"]
}]);
flex(100, 1);
// 高清方案默认1rem=100px,那么 btn的宽度就设置为:)
.btn {
width:0.8rem
height:1.2rem
}
【7】 移动端开发自适应解决方案(阿里团队高清方案)
同时兼任pc和移动适配
通过配置两套不同路由和判断是否是移动端实现
核心代码:router.addRoute(isMobile() ? mobileRoutes[1] : pcRoutes[1]);(区分路由)
搭配工程化,可以参考第二章【PC端适配方案】
npm i postcss-pxtorem --save-dev
//使用postcss-pxtorem
module.exports = {
lintOnSave:true,
css:{
loaderOptions:{
postcss:[
require('postcss-pxtorem')({
rootValue:16,//根元素字体大小
unitPrecision:5, //允许rem单位增长的十进制数字
replace:true, //替换包含rems的规则,而不添加后备
mediaQuery:false, //允许在媒体查询中转换px
minPixelValue:0, //设置要替换的最小像素值
selectorBlackList:[], //忽略转换正则匹配项
propList:['*'], //可以从px转换为rem的属性,匹配正则
exclude:/node_modules/i 要忽略并保留为px的文件路径
}),
]
}
}
}
vue项目使用element-ui框架Rem适配(postcss-pxtorem、amfe-flexible),自动转换px为rem,解决响应式问题
1366 * 768 : 普通液晶显示器 1920 * 1080: 高清液晶显示器 2560 * 1440: 2K高清显示器 4096 * 2160: 4K高清显示器 1280 * 720: 笔记本(1920*1080分辨率下系统默认推荐150%缩放比产生的尺寸)
大屏数据可视化项目通常用于放在电视或广告屏上展示用,而不允许出现滚动条
设计稿按照1920*1080的分辨率,16:9的比例设计, 实际开发中,document窗口不足16:9(高度减掉顶部tab及导航栏,地址栏等) 不同分辨率:实际应用场景中,显示场景不同,不能固定写死px单位 不同比例:不同的显示器宽高比与设计稿不一致
rem是CSS3新增的相对长度单位,是指相对于根元素html的font-size计算值的大小。简单可理解为屏幕宽度的百分比。 但是,项目中常见尺寸绘制采用的均是px,要改用rem一时半会缓不过来,而且可能还要换算转换,所以使用rem还是比较麻烦的,但是,我们可以通过插件,能够将项目中的px转换为rem,还可以自定义基数。
npm install amfe-flexible // CSS单位自适应转换插件 负责更改根font-size
npm install postcss-pxtorem@^5.1.1 // 如果版本过高可以降版本下载5.1.1版本 负责将px转成rem
// 用途:echarts字体适配
/**
* echarts字体自适应
* @param {*} font 字号大小
*/
export function echartGetFontSize(font) {
let docEl = document.documentElement,
clientWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
if (!clientWidth) return;
let fontSize = clientWidth / 1920;
return font * fontSize;
}
由于 viewport 单位得到众多浏览器的兼容,lib-flexible 这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用 viewport 来替代此方。(待考证?)
amfe-flexible是lib-flexible的升级版
flexible就是根据不同的屏幕算出html的font-size,通过js来动态写meta标签
实上他做了这几样事情:
在main.js中引入amfe-flexible
import "amfe-flexible"
amfe-flexible 等价代码
// import '@/utils/rem.js'
// 在utils文件夹下创建rem.js
// 设置 rem 函数
function setRem() {
// 1920 默认大小16px; 1920px = 120rem ;每个元素px基础上/16
const screenWidth = 1920
const scale = screenWidth / 16
const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
// 得到html的Dom元素
const htmlDom = document.getElementsByTagName('html')[0]
// 设置根元素字体大小
htmlDom.style.fontSize = htmlWidth / scale + 'px'
}
// 初始化
setRem()
// 改变窗口大小时重新设置 rem
window.onresize = function() {
setRem()
}
配置postcss-pxtorem ,可在vue.config.js、postcsssrc.js、postcss.config.js、其中之一配置,权重从左到右降低,没有则新建文件,只需要设置其中一个即可.
/***
注意点:
(1)rootValue根据设计稿宽度除以10进行设置,这边假设设计稿为1920,即rootValue设为192;
(2)propList是设置需要转换的属性,这边*为所有都进行转换。
***/
module.exports=function(){
devServer:{
port:3000,
open:true
},
//rem配置
css: {
loaderOptions: {
postcss: {
plugins: [
require('postcss-pxtorem')({
rootValue: 192, //根元素字体大小
propList: ['*'], //可以从px转换为rem的属性,匹配正则
// unitPrecision:5, //允许rem单位增长的十进制数字
// replace:true, //替换包含rems的规则,而不添加后备
// mediaQuery:false, //允许在媒体查询中转换px
// minPixelValue:0, //设置要替换的最小像素值
// selectorBlackList:[], //忽略转换正则匹配项
// exclude:/node_modules/i 要忽略并保留为px的文件路径
})
]
}
}
},
}
// 效果展示 在html上增加根font-size
<html lang="en” style="font-size: 192px;class="light-themes">
对于行内样式,阿里手淘并不能将px转rem,所以对于需要自适应的样式,如font-size、width、height等请不要写在行内。同理,对于不需要转化的样式可以写在行内,或者使用PX(大写)作为单位。
暂未找到可以转行内rem的插件,可根据下面地址的方式自己实现(未验证是否可行)。blog.csdn.net/weixin_3961…
我们都知道chrome的最小显示的字体是12px,如果字体用rem,计算出来小于12px,那么就也会以12px显示,而且我们不希望出现13px或者15px这样的奇葩尺寸,所以字体最好是用PX(大写)来表示,至于适应,我们可以写媒体查询。
.item {
border-bottom: 1PX #8d8d8d dashed;
font-size: 12PX;
line-height: 16PX;
@media screen and (min-width: 576PX) {
font-size: 14PX;
line-height: 18PX;
}
@media screen and (min-width: 768PX) {
font-size: 16PX;
line-height: 28PX;
}
@media screen and (min-width: 992PX) {
font-size: 16PX;
line-height: 32PX;
}
@media screen and (min-width: 1200PX) {
font-size: 18PX;
line-height: 64PX;
}
}
PC端响应式媒体断点:
```css
@media (min-width: 1024px){
body{font-size: 18px}
} /*>=1024的设备*/
@media (min-width: 1100px) {
body{font-size: 20px}
} /*>=1100的设备*/
@media (min-width: 1280px) {
body{font-size: 22px;}
} /*>=1280的设备*/
@media (min-width: 1366px) {
body{font-size: 24px;}
}
@media (min-width: 1440px) {
body{font-size: 25px !important;}
}
@media (min-width: 1680px) {
body{font-size: 28px;}
}
@media (min-width: 1920px) {
body{font-size: 33px;}
}
```
已测试屏幕尺寸:1920*1080 、1366 * 768
问题:屏幕缩小,网页缩放,效果与原1920*1080不一致
// 仅在移动端时候生效,或者浏览器手机模式
// 整体缩放自适应解决方案(阿里团队高清方案)
! function (e) {
function t(a) {
if (i[a]) return i[a].exports;
var n = i[a] = {
exports: {},
id: a,
loaded: !1
};
return e[a].call(n.exports, n, n.exports, t), n.loaded = !0, n.exports
}
var i = {};
return t.m = e, t.c = i, t.p = "", t(0)
}([function (e, t) {
"use strict";
Object.defineProperty(t, "__esModule", {
value: !0
});
var i = window;
t["default"] = i.flex = function (e, t) {
var a = e || 100,
n = t || 1,
r = i.document,
o = navigator.userAgent,
d = o.match(/Android[\S\s]+AppleWebkit/(\d{3})/i),
l = o.match(/U3/((\d+|.){5,})/i),
c = l && parseInt(l[1].split(".").join(""), 10) >= 80,
p = navigator.appVersion.match(/(iphone|ipad|ipod)/gi),
s = i.devicePixelRatio || 1;
p || d && d[1] > 534 || c || (s = 1);
var u = 1 / s,
m = r.querySelector('meta[name="viewport"]');
m || (m = r.createElement("meta"), m.setAttribute("name", "viewport"), r.head.appendChild(m)), m
.setAttribute("content", "width=device-width,user-scalable=no,initial-scale=" + u + ",maximum-scale=" +
u + ",minimum-scale=" + u), r.documentElement.style.fontSize = a / 2 * s * n + "px"
}, e.exports = t["default"]
}]);
flex(100, 1);
“node-sass”: “^4.9.0”,
“sass-loader”: “^7.1.0”
作者:幸运_
链接:https://juejin.cn/post/7278646930174165050
着就能变瘦变白,是所有减肥/美白人群的终极梦想,于是很多人纷纷投向了医疗美容。
为了满足广大爱美人士的需求,两款神奇的产品诞生了——美白针、溶脂针。
其实这两种产品都是不合法的医美项目,在我们国家都没有被批准。
如果你也种草了/做过这两个项目,请一定要认真看这篇文章。
动图来源于千库网
先来说说「美白针」。
「美白针」是通过静脉注射药物,达到美白效果的一种手段。
它的主要成分是传明酸(氨甲环酸)、维C、谷胱甘肽等, 这几个成分在化妆品里经常见到,都有一定美白作用。
那是不是注射的效果更好呢?
效果好不好不知道,风险是很大的。
首先「美白针」并不是一种药物,而是几种不同的针剂的组合,加在一起静脉注射。
这几种针剂的配比是厂家自己配制的,并没有一个标准配比。
这些药物经血流向多个组织器官,必然会有药物的主要适应症效果产生,比如凝血。
在无凝血性障碍的情况下,注射抗纤溶药物,是不明智的。
其次,国家批准这些药物(传明酸、谷胱甘肽),并不是用于美白,而是用来治疗其他疾病的。
比如传明酸是用来凝血的,而谷胱甘肽在临床上是用来保肝的。
而商家并没有按照药品上的指示用药,而是根据自己的理解,用于治疗美白。
更有甚者为了达到美白效果,会加大剂量,可能会损伤肾功能,带来很大的副作用。
要知道其实不光是中国没批准这类医美项目,美国FDA也没批准过注射用的美白产品。
再来说说「溶脂针」。
「溶脂针」是注射入人体后,让脸、下巴、腿变瘦的针剂。
「溶脂针」的主要成分是磷脂酰胆碱(ppc)、利多卡因(麻醉剂)、肾上腺素及生理盐水。
主要原理是通过磷脂酰胆碱(ppc)的乳化作用将局部脂肪乳化为小颗粒,用膨胀液辅助,加快脂肪从淋巴管代谢,起到溶脂的作用。
但溶脂针里的药物成分利多卡因、肾上腺素等如果被血液系统吸收后,会给身体带来不同程度的副作用,比如头晕、恶心、心动过速、呼吸困难、血压下降等。
当麻醉剂用量过大时,也存在生命危险。
而且溶脂针没有有效地降低脂肪细胞数量,如果不控制饮食的话,还是会反弹的。
动图来源于soogif
在国外,有部分品牌的溶脂针获得了批文,可以注射使用(例如祛除双下巴),但它在成分、治疗效果、安全方面还存在很多问题。
在国内,虽然有部分品牌拿到了批文,不过是妆字号的。
也就是说,在国内溶脂针可以外用涂抹皮肤,但用于皮下注射是不合法的,在正规的医美机构是没有的。
动图来源于soogif
虽然美白针和溶脂针,在国内都是不合法的医美项目,但是在医美网站上还是能看到它们的身影。
希望有关部门加强监管,也希望各位爱美人士一定要慎重。
爱美没有错,人人都喜欢追求美。
但如果你想去做医美项目,一定要选择正规的医疗机构和执业医师,切记要看看有没有资质证明,
远离那些来源不明「三无产品」。
毕竟脸只有一张,仙女们请慎重选择呀~
别忘了转告自己最好的小姐妹,一起避雷,一起变美。
参考资料:
1.上海卫健委,沪卫监部门加强医疗美容领域监管!来看警示案例http://wsjkw.sh.gov.cn/gzdt1/20200708/1bcd29f7cfa641979660a4f92520ab7a.html
2.《每周质量报告》 20131201黑心美白针。http://tv.cctv.com/2013/12/01/VIDE1385876522401836.shtml
*请认真填写需求信息,我们会在24小时内与您取得联系。