想必近幾年前端的數據可視化越來越重要了,很多甲方爸爸都喜歡那種炫酷的大屏幕設計,類似如下這種:

隨便找的.jpg
遇到的這樣的項目,二話不說,echarts或者antv,再搭配各種mvvm框架(react,vue),找二次封裝過的組件,然后開始埋頭開始寫了,寫着寫着你會發現,如何適配不同屏幕呢?css媒體查詢吧,用vw吧,哪個好點呢。其實寫到最后,我覺得都不好
對於這種拿不定主意的情況呢,最好還是參考大廠的做法,於是去找了網易有數,百度suger等,他們是如何寫這樣的頁面的
提供2個他們的案例鏈接:
百度
網易有數
仔細觀察他們都采用了css3的縮放transform: scale(X)
屬性,看到這是不是有種豁然開朗的感覺
於是我們只要監聽瀏覽器的窗口大小,然后控制變化的比例就好了
以React的寫法為例
getScale=() => { // 固定好16:9的寬高比,計算出最合適的縮放比,寬高比可根據需要自行更改 const {width=1920, height=1080} = this.props let ww=window.innerWidth/width let wh=window.innerHeight/height return ww<wh?ww: wh } setScale = debounce(() => { // 獲取到縮放比,設置它 let scale=this.getScale() this.setState({ scale }) }, 500)
監聽window的resize
事件最好加個節流函數debounce
window.addEventListener('resize', this.setScale)
然后一個簡單的組件就封裝好了
import React, { Component } from 'react'; import debounce from 'lodash.debounce' import s from './index.less' class Comp extends Component{ constructor(p) { super(p) this.state={ scale: this.getScale() } } componentDidMount() { window.addEventListener('resize', this.setScale) } getScale=() => { const {width=1920, height=1080} = this.props let ww=window.innerWidth/width let wh=window.innerHeight/height return ww<wh?ww: wh } setScale = debounce(() => { let scale=this.getScale() this.setState({ scale }) }, 500) render() { const {width=1920, height=1080, children} = this.props const {scale} = this.state return( <div className={s['scale-box']} style={{ transform: `scale(${scale}) translate(-50%, -50%)`, WebkitTransform: `scale(${scale}) translate(-50%, -50%)`, width, height }} > {children} </div> ) } componentWillUnmount() { window.removeEventListener('resize', this.setScale) } } export default Comp
.scale-box{ transform-origin: 0 0; position: absolute; left: 50%; top: 50%; transition: 0.3s; }
只要把頁面放在這個組件中,就能實現跟大廠們類似的效果。這種方式下不管屏幕有多大,分辨率有多高,只要屏幕的比例跟你定的比例一致,都能呈現出完美效果。而且開發過程中,樣式的單位也可以直接用px,省去了轉換的煩惱~~~
注:圖表插件bizcharts在css縮放下會有鼠標移入時像素偏移的bug,由於是基於antv的,這主要是antv的bug,我寫這篇文章的時候官方還未修復這個bug,echarts沒有這個bug。
最后附上npm鏈接:https://www.npmjs.com/package/react-scale-box
作者:安東尼的漫長歲月
鏈接:https://www.jianshu.com/p/b2fd58d31515
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。