如何實現canvas根據父容器進行自適應?
Ant Design的組件都提供了強大的自適應能力,為了對齊父組件,鑲嵌在Ant Design組件里的canvas也需要能根據父級容器進行自適應的能力,頁面高度一般不用做自適應,因為即使太多內容頁面太長,也會出現滾動條,所以問題不大,問題在於寬度,屏幕尺寸各不同,如果寬度不夠,元素就會被擠變形或者換行
步驟:
首先,固定canvas的height,對於width
1、實時獲取父組件的尺寸
2、實時修改canvas的尺寸
1
這里使用一個npm的包,可以很輕松的實時獲取某節點的尺寸:
npm install resize-observer-polyfill --save-dev
用法 :首先在父節點下創建一個div,父節點,div,canvas的關系如下:
<父組件> <div> <Canvas></Canvas> </div> </父組件>
然后,利用ref讀到DOM節點,如下
<父組件> <div ref={this.refHandle}> <Canvas></Canvas> </div> </父組件>
constructor(props) { super(props); this.state = { cvWidth: null } }
refHandle = (cw) => { // containerWrap if (cw) { const ro = new ResizeObserver((entries, observer) => { // eslint-disable-next-line no-restricted-syntax for (const entry of entries) { const { left, top, width, height } = entry.contentRect; // console.log('Element:', entry.target); // console.log(`Element's size: ${width}px x ${height}px`); // console.log(`Element's paddings: ${top}px ; ${left}px`); console.log(`Element's size: ${width} x ${height} `); this.setState({ cvWidth: width }) } }); ro.observe(cw); } };
{ cvWidth && <Canvas cvWidth={cvWidth } /> }
2 在Canvas組件里
使用以下生命周期,為了避免不必要的渲染,當新舊cvWidth一樣時不進行重新渲染
componentWillReceiveProps
componentWillReceiveProps(nextProps) { const { ...data } = this.props const { ...newData } = nextProps if (data.cvWidth !== newData.cvWidth) { this.canvas.width = newData.cvWidth this.canvasRender(newData) } }
this.canvas是我創建的canvas實例,canvasRender是我的canvas畫圖函數,你可以換成你自己的,最后在this.canvas開頭加一行
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
防止圖像重疊
PS:我的父組件,使用了Row+Col,並且Col使用了span,因此一開始Row+Col就有寬度
另外,如果要實現寬高自適應,請參考G2+bizcharts的源碼,先看bizcharts的Chart組件