陈宏源 發表於 2019-11-26 16:35:00

react实战 : react 与 canvas

<p>有一个需求是这样的。</p>
<p>一个组件里若干个区块。区块数量不定。</p>
<p>区块里面是一个正六边形组件,而这个用 SVG 和 canvas 都可以。我选择 canvas。</p>
<p>所以就变成了在 react 中使用 canvas 的问题。</p>
<p>&nbsp;</p>
<p>canvas 和 SVG 有一个很大的不同。</p>
<p>SVG 是标签,所以HTML怎么整,SVG 就怎么整。</p>
<p>而 canvas 是一套相对独立的 web API,以 canvas 标签为容器(HTML接口)。</p>
<p>所以在 react 中处理 canvas 类似于在 react 中处理第三方DOM库。比如那些需要依赖 jQuery 的各种UI组件库。</p>
<p>关于这个可以看 react 文档中的与第三方库协同。</p>
<p>&nbsp;</p>
<p>组件文件的结构和上一个文章类似。</p>
<div class="cnblogs_code">
<pre>import React from 'react'<span style="color: rgba(0, 0, 0, 1)">

class Polygon extends React.Component {}

class polygonContainer extends React.Component {}

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> polygonContainer</pre>
</div>
<p>&nbsp;</p>
<p>然后是 canvas 组件。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">class Polygon extends React.Component {
constructor(props){
    super(props)
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.state =<span style="color: rgba(0, 0, 0, 1)"> {
    }
}

componentDidMount() {
    console.log(</span>"=== componentDidMount Polygon ==="<span style="color: rgba(0, 0, 0, 1)">)

    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.init(<span style="color: rgba(0, 0, 255, 1)">this</span>.props.data, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.sn)
}

componentDidUpdate() {
    console.log(</span>"=== componentDidUpdate Polygon ==="<span style="color: rgba(0, 0, 0, 1)">)

    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.init(<span style="color: rgba(0, 0, 255, 1)">this</span>.props.data, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.sn)
}

init </span>= (item, sn) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {

    const getR </span>= () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> Math.min(size.width, size.height) * 0.375<span style="color: rgba(0, 0, 0, 1)">
    }

    const getWordCoor </span>= (index, centerCoor, sub, fontSize, fontLength) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const getXCoor </span>= (index, centerCoor, fontSize, fontLength) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const standand </span>= -1
      <span style="color: rgba(0, 0, 255, 1)">return</span> (centerCoor.x + fontLength / 2 * (index === 0 ? fontSize : (fontSize / 2)) *<span style="color: rgba(0, 0, 0, 1)"> standand)
      }
      const getYCoor </span>= (index, centerCoor, sub) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const standand </span>= index === 0 ? -0.3 : 0.6
      <span style="color: rgba(0, 0, 255, 1)">return</span> (centerCoor.y + sub *<span style="color: rgba(0, 0, 0, 1)"> standand)
      }

      console.log(getXCoor(index, centerCoor, fontSize, fontLength))

      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
      x: getXCoor(index, centerCoor, fontSize, fontLength),
      y: getYCoor(index, centerCoor, sub)
      }
    }

    const getStrokeColor </span>= (sn) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> sn === 5 ? 'rgb(255, 114, 0)' : 'rgb(232, 172, 4)'<span style="color: rgba(0, 0, 0, 1)">
    }

    const getFillColor </span>= (sn) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> sn === 5 ? 'rgb(255, 192, 0)' : 'rgb(4, 154, 79)'<span style="color: rgba(0, 0, 0, 1)">
    }
   
    const canvas </span>= document.getElementById("canvas" +<span style="color: rgba(0, 0, 0, 1)"> sn);

    const size </span>=<span style="color: rgba(0, 0, 0, 1)"> {
      width: parseInt(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.size.width),
      height: parseInt(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.size.height),
    }

    canvas.width </span>=<span style="color: rgba(0, 0, 0, 1)"> size.width;
    canvas.height </span>=<span style="color: rgba(0, 0, 0, 1)"> size.height;
    const cc </span>= canvas.getContext("2d"<span style="color: rgba(0, 0, 0, 1)">);

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 多边形</span>
    const coorArray =<span style="color: rgba(0, 0, 0, 1)"> []

    cc.beginPath();
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> i = 0 ; i &lt; 6 ; i++<span style="color: rgba(0, 0, 0, 1)">) {
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> x =Math.cos((i * 60)/180 * Math.PI) * getR() + (size.width / 2<span style="color: rgba(0, 0, 0, 1)">) ;
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> y = -Math.sin((i * 60)/180 * Math.PI) * getR() + (size.height / 2<span style="color: rgba(0, 0, 0, 1)">);   

      coorArray.push({x, y})

      cc.lineTo(x,y);
    }
    cc.closePath();
    cc.lineWidth </span>= 2<span style="color: rgba(0, 0, 0, 1)">;
    cc.fillStyle </span>=<span style="color: rgba(0, 0, 0, 1)"> getFillColor(sn);
    cc.fill();
    cc.strokeStyle </span>=<span style="color: rgba(0, 0, 0, 1)"> getStrokeColor(sn);
    cc.stroke();

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 文字</span>
    const centerCoor =<span style="color: rgba(0, 0, 0, 1)"> {
      x: (coorArray[</span>0].x + coorArray.x) / 2<span style="color: rgba(0, 0, 0, 1)">,
      y: coorArray[</span>0<span style="color: rgba(0, 0, 0, 1)">].y
    }
    const sub </span>= coorArray.y - coorArray.y

    const wordCoorArray </span>=<span style="color: rgba(0, 0, 0, 1)"> [
      getWordCoor(</span>0, centerCoor, sub, 14<span style="color: rgba(0, 0, 0, 1)">, item.name.length),
      getWordCoor(</span>1, centerCoor, sub, 20<span style="color: rgba(0, 0, 0, 1)">, item.data.toString().length)
    ]

    cc.font</span>="14px Arial"<span style="color: rgba(0, 0, 0, 1)">
    cc.strokeStyle </span>= "#fff"<span style="color: rgba(0, 0, 0, 1)">;
    cc.fillStyle </span>= "#fff"<span style="color: rgba(0, 0, 0, 1)">;
    cc.fillText(item.name, wordCoorArray[</span>0].x, wordCoorArray.y);

    cc.font</span>="20px Arial"<span style="color: rgba(0, 0, 0, 1)">
    cc.fillText(item.data, wordCoorArray[</span>1].x, wordCoorArray.y);
}

render(){
    const item </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.data
    const size </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.size
    const sn </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.sn

    const getColor </span>= (item) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> item.color
    }

    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
      </span>&lt;canvas id={'canvas' + sn}&gt;&lt;/canvas&gt;
<span style="color: rgba(0, 0, 0, 1)">    );
}
}</span></pre>
</div>
<p>有几点需要说明一下。</p>
<ul>
<li>因为&nbsp;componentDidUpdate 钩子中 有 init 方法,所以 init 方法中不能再给 state 赋值,否则会触发无限循环。如果需要存值,则需要想别的办法。</li>
<li>
<div>getWordCoor 是计算文字位置的方法。六边形里面有文字内容。</div>
</li>
<li>canvas 对象是通过 document.getElementById 获取的,而一个页面中肯定有多个 canvas ,此时就必须做出区分。我的方法是传一个序列号 sn (index + 1),当然生成 ID 是更好的做法。</li>
<li>响应式的样式对 canvas 是无效的。必须手动赋像素值。也就是说必须手动计算 size 。计算 size 的方法在父组件里面。</li>
<li>for 循环是用来绘制路径的,就是个数学问题,Math 对象里有三角函数简化了一些运算。顺便把中心点坐标和六边形各个点的坐标存了一下。</li>
<li>canvas 绘制方法不需要说了,百度一下即可。</li>
</ul>
<p>&nbsp;</p>
<p>然后是容器组件。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 六边形测试</span>
<span style="color: rgba(0, 0, 0, 1)">
import React from </span>'react'

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> import Styles from './polygonContainer.less'</span>
<span style="color: rgba(0, 0, 0, 1)">
class Polygon extends React.Component {
constructor(props){
    super(props)
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.state =<span style="color: rgba(0, 0, 0, 1)"> {
    }
}

componentDidMount() {
    console.log(</span>"=== componentDidMount Polygon ==="<span style="color: rgba(0, 0, 0, 1)">)

    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.init(<span style="color: rgba(0, 0, 255, 1)">this</span>.props.data, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.sn)
}

componentDidUpdate() {
    console.log(</span>"=== componentDidUpdate Polygon ==="<span style="color: rgba(0, 0, 0, 1)">)

    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.init(<span style="color: rgba(0, 0, 255, 1)">this</span>.props.data, <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.sn)
}

init </span>= (item, sn) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(item)</span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(sn)</span>
<span style="color: rgba(0, 0, 0, 1)">
    const getR </span>= () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> Math.min(size.width, size.height) * 0.375<span style="color: rgba(0, 0, 0, 1)">
    }

    const getWordCoor </span>= (index, centerCoor, sub, fontSize, fontLength) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const getXCoor </span>= (index, centerCoor, fontSize, fontLength) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const standand </span>= -1
      <span style="color: rgba(0, 0, 255, 1)">return</span> (centerCoor.x + fontLength / 2 * (index === 0 ? fontSize : (fontSize / 2)) *<span style="color: rgba(0, 0, 0, 1)"> standand)
      }
      const getYCoor </span>= (index, centerCoor, sub) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      const standand </span>= index === 0 ? -0.3 : 0.6
      <span style="color: rgba(0, 0, 255, 1)">return</span> (centerCoor.y + sub *<span style="color: rgba(0, 0, 0, 1)"> standand)
      }

      console.log(getXCoor(index, centerCoor, fontSize, fontLength))

      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
      x: getXCoor(index, centerCoor, fontSize, fontLength),
      y: getYCoor(index, centerCoor, sub)
      }
    }

    const getStrokeColor </span>= (sn) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> sn === 5 ? 'rgb(255, 114, 0)' : 'rgb(232, 172, 4)'<span style="color: rgba(0, 0, 0, 1)">
    }

    const getFillColor </span>= (sn) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> sn === 5 ? 'rgb(255, 192, 0)' : 'rgb(4, 154, 79)'<span style="color: rgba(0, 0, 0, 1)">
    }
   
    const canvas </span>= document.getElementById("canvas" +<span style="color: rgba(0, 0, 0, 1)"> sn);

    const size </span>=<span style="color: rgba(0, 0, 0, 1)"> {
      width: parseInt(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.size.width),
      height: parseInt(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.size.height),
    }

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(size)</span>
<span style="color: rgba(0, 0, 0, 1)">   
    canvas.width </span>=<span style="color: rgba(0, 0, 0, 1)"> size.width;
    canvas.height </span>=<span style="color: rgba(0, 0, 0, 1)"> size.height;
    const cc </span>= canvas.getContext("2d"<span style="color: rgba(0, 0, 0, 1)">);

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 多边形</span>
    const coorArray =<span style="color: rgba(0, 0, 0, 1)"> []

    cc.beginPath();
    </span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> i = 0 ; i &lt; 6 ; i++<span style="color: rgba(0, 0, 0, 1)">) {
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> x =Math.cos((i * 60)/180 * Math.PI) * getR() + (size.width / 2<span style="color: rgba(0, 0, 0, 1)">) ;
      </span><span style="color: rgba(0, 0, 255, 1)">var</span> y = -Math.sin((i * 60)/180 * Math.PI) * getR() + (size.height / 2<span style="color: rgba(0, 0, 0, 1)">);   

      coorArray.push({x, y})

      cc.lineTo(x,y);
    }
    cc.closePath();
    cc.lineWidth </span>= 2<span style="color: rgba(0, 0, 0, 1)">;
    cc.fillStyle </span>=<span style="color: rgba(0, 0, 0, 1)"> getFillColor(sn);
    cc.fill();
    cc.strokeStyle </span>=<span style="color: rgba(0, 0, 0, 1)"> getStrokeColor(sn);
    cc.stroke();

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 文字</span>
    const centerCoor =<span style="color: rgba(0, 0, 0, 1)"> {
      x: (coorArray[</span>0].x + coorArray.x) / 2<span style="color: rgba(0, 0, 0, 1)">,
      y: coorArray[</span>0<span style="color: rgba(0, 0, 0, 1)">].y
    }
    const sub </span>= coorArray.y - coorArray.y

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(centerCoor)</span>
    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(coorArray)</span>
<span style="color: rgba(0, 0, 0, 1)">
    const wordCoorArray </span>=<span style="color: rgba(0, 0, 0, 1)"> [
      getWordCoor(</span>0, centerCoor, sub, 14<span style="color: rgba(0, 0, 0, 1)">, item.name.length),
      getWordCoor(</span>1, centerCoor, sub, 20<span style="color: rgba(0, 0, 0, 1)">, item.data.toString().length)
    ]
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(wordCoorArray)</span>
<span style="color: rgba(0, 0, 0, 1)">
    cc.font</span>="14px Arial"<span style="color: rgba(0, 0, 0, 1)">
    cc.strokeStyle </span>= "#fff"<span style="color: rgba(0, 0, 0, 1)">;
    cc.fillStyle </span>= "#fff"<span style="color: rgba(0, 0, 0, 1)">;
    cc.fillText(item.name, wordCoorArray[</span>0].x, wordCoorArray.y);

    cc.font</span>="20px Arial"<span style="color: rgba(0, 0, 0, 1)">
    cc.fillText(item.data, wordCoorArray[</span>1].x, wordCoorArray.y);
}

render(){
    const item </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.data
    const size </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.size
    const sn </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.sn

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log("Polygon render === ", size)</span>
<span style="color: rgba(0, 0, 0, 1)">
    const getColor </span>= (item) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> item.color
    }

    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
      </span>&lt;canvas id={'canvas' + sn}&gt;&lt;/canvas&gt;
      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> &lt;div&gt;asd&lt;/div&gt;</span>
<span style="color: rgba(0, 0, 0, 1)">    );
}
}

class polygonContainer extends React.Component {
constructor(props){
    super(props)
    </span><span style="color: rgba(0, 0, 255, 1)">this</span>.state =<span style="color: rgba(0, 0, 0, 1)"> {
      curcity:</span>""<span style="color: rgba(0, 0, 0, 1)">
    }
}

componentDidMount() {
    console.log(</span>"componentDidMount"<span style="color: rgba(0, 0, 0, 1)">)
    console.log(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date().getTime())

    </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.setState({
      curcity:</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.props.curcity
    })
}

componentDidUpdate(){
    console.log(</span>"componentDidUpdate"<span style="color: rgba(0, 0, 0, 1)">)
    console.log(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Date().getTime())
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> total 总数 SN 序列号</span>
getSize = () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    const pc </span>= document.getElementById('pc'<span style="color: rgba(0, 0, 0, 1)">)
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">pc) {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">
    } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> const length = this.getDataBar().data.sData.length</span>
<span style="color: rgba(0, 0, 0, 1)">
      const base </span>=<span style="color: rgba(0, 0, 0, 1)"> {
      width:document.getElementById(</span>'pc'<span style="color: rgba(0, 0, 0, 1)">).offsetWidth,
      height:document.getElementById(</span>'pc'<span style="color: rgba(0, 0, 0, 1)">).offsetHeight
      }

      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (total, SN) {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(base)</span>
<span style="color: rgba(0, 0, 0, 1)">
      const standand </span>= 2<span style="color: rgba(0, 0, 0, 1)">
      const oneRowStd </span>= 3<span style="color: rgba(0, 0, 0, 1)">

      const ceil </span>= Math.ceil(total /<span style="color: rgba(0, 0, 0, 1)"> standand)
      const floor </span>= Math.floor(total /<span style="color: rgba(0, 0, 0, 1)"> standand)
      
      const basicHeight </span>= (total &gt; oneRowStd) ? (base.height /<span style="color: rgba(0, 0, 0, 1)"> standand) : (base.height)

      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(ceil, floor)</span>
      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(total, SN)</span>

      <span style="color: rgba(0, 0, 255, 1)">if</span> (SN &lt;=<span style="color: rgba(0, 0, 0, 1)"> ceil) {
          </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
            width:(total </span>&gt; oneRowStd) ? (base.width / ceil) : (base.width /<span style="color: rgba(0, 0, 0, 1)"> total),
            height:basicHeight
          }
      } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
          </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log(123)</span>
          <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> console.log((total &gt; oneRowStd) ? (base.width / floor) : (base.width / total))</span>

          <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
            width:(total </span>&gt; oneRowStd) ? (base.width / floor) : (base.width /<span style="color: rgba(0, 0, 0, 1)"> total) ,
            height:basicHeight
          }
      }
      }
    }
}

theStyle </span>= () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    const baseFlex </span>=<span style="color: rgba(0, 0, 0, 1)"> {
      display: </span>'flex'<span style="color: rgba(0, 0, 0, 1)">,
      justifyContent: </span>'center'<span style="color: rgba(0, 0, 0, 1)">,
      alignItems: </span>'center'<span style="color: rgba(0, 0, 0, 1)">
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
      main:{
      ...baseFlex,
      width:</span>'100%'<span style="color: rgba(0, 0, 0, 1)">,
      height:</span>'100%'<span style="color: rgba(0, 0, 0, 1)">,
      color:</span>"#fff"<span style="color: rgba(0, 0, 0, 1)">
      },
      tem:{
      ...baseFlex,
      flex:</span>"auto"<span style="color: rgba(0, 0, 0, 1)">,
      color:</span>'#fff'<span style="color: rgba(0, 0, 0, 1)">
      },
      shellA:{
      ...baseFlex,
      width:</span>'100%'<span style="color: rgba(0, 0, 0, 1)">,
      height:</span>'100%'<span style="color: rgba(0, 0, 0, 1)">
      },
      shellB:{
      ...baseFlex,
      width:</span>'100%'<span style="color: rgba(0, 0, 0, 1)">,
      height:</span>'50%'<span style="color: rgba(0, 0, 0, 1)">
      }
    }
}

getDataBar </span>= () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (<span style="color: rgba(0, 0, 255, 1)">this</span>.props.curcity &amp;&amp; <span style="color: rgba(0, 0, 255, 1)">this</span>.props.curcity === 'all'<span style="color: rgba(0, 0, 0, 1)">) {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
      data:{
          sData:[
            { name: </span>'a', data: 510<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 46<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 471<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 631<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 924<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 582<span style="color: rgba(0, 0, 0, 1)"> },
          ]
      }
      }
    } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
      data:{
          sData:[
            { name: </span>'a', data: 50<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 469<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 41<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 31<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 4<span style="color: rgba(0, 0, 0, 1)"> },
            { name: </span>'a', data: 825<span style="color: rgba(0, 0, 0, 1)"> },
          ]
      }
      }
    }
}

getContainer </span>= () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    const size </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getSize()

    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">size) {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> ""<span style="color: rgba(0, 0, 0, 1)">
    }

    const theStyle </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.theStyle()

    const dataBar </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getDataBar()

    const Container </span>= ((dataBar) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {

      const flexMatrix </span>=<span style="color: rgba(0, 0, 0, 1)"> [
      [</span>0,0<span style="color: rgba(0, 0, 0, 1)">],
      [</span>1,0<span style="color: rgba(0, 0, 0, 1)">],
      [</span>2,0<span style="color: rgba(0, 0, 0, 1)">],
      [</span>3,0<span style="color: rgba(0, 0, 0, 1)">],
      [</span>2,2<span style="color: rgba(0, 0, 0, 1)">],
      [</span>3,2<span style="color: rgba(0, 0, 0, 1)">],
      [</span>3,3<span style="color: rgba(0, 0, 0, 1)">],
      [</span>4,3<span style="color: rgba(0, 0, 0, 1)">],
      [</span>4,4<span style="color: rgba(0, 0, 0, 1)">],
      [</span>5,4<span style="color: rgba(0, 0, 0, 1)">],
      [</span>5,5<span style="color: rgba(0, 0, 0, 1)">],
      [</span>6,5<span style="color: rgba(0, 0, 0, 1)">],
      [</span>6,6<span style="color: rgba(0, 0, 0, 1)">]
      ]

      const sData </span>=<span style="color: rgba(0, 0, 0, 1)"> dataBar.data.sData
      const length </span>=<span style="color: rgba(0, 0, 0, 1)"> sData.length

      const matrix </span>= flexMatrix ? flexMatrix : flexMatrix

      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (matrix === 0<span style="color: rgba(0, 0, 0, 1)">) {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> ""<span style="color: rgba(0, 0, 0, 1)">
      }

      let temShell, temA, temB

      temA </span>= sData.slice(0, matrix).map((item, index) =&gt;
      &lt;div style={theStyle.tem} key={index.toString()}&gt; &lt;Polygon data={item} sn={index + 1} size={size(length, (index + 1))} /&gt; &lt;/div&gt;<span style="color: rgba(0, 0, 0, 1)">
      );

      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (matrix === 0<span style="color: rgba(0, 0, 0, 1)">) {
      temB </span>= ""<span style="color: rgba(0, 0, 0, 1)">
      } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      temB </span>= sData.slice(matrix, (matrix + matrix)).map((item, index) =&gt;
          &lt;div style={theStyle.tem} key={index.toString()}&gt; &lt;Polygon data={item} sn={index + 1 + matrix} size={size(length, (index + 1 + matrix))} /&gt; &lt;/div&gt;<span style="color: rgba(0, 0, 0, 1)">
      );
      }

      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (matrix === 0<span style="color: rgba(0, 0, 0, 1)">) {
      temShell </span>= &lt;div style={theStyle.shellA} &gt; {temA} &lt;/div&gt;
      } <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      temShell </span>= .map((item, index) =&gt;
          &lt;div style={theStyle.shellB} key={"temShell" + index.toString()}&gt; {index === 0 ? temA : temB} &lt;/div&gt;
<span style="color: rgba(0, 0, 0, 1)">      );

      document.getElementById(</span>'pc').style.flexWrap = "wrap"<span style="color: rgba(0, 0, 0, 1)">
      }

      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> temShell
    })(dataBar)

    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Container
}

render(){

    const theStyle </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.theStyle()
    const curcity </span>= <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.state.curcity

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> const dataBar = this.props.dataBar</span>

    <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
      </span>&lt;div style={theStyle.main} id="pc"&gt;<span style="color: rgba(0, 0, 0, 1)">
      { </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.getContainer() }
      </span>&lt;/div&gt;
<span style="color: rgba(0, 0, 0, 1)">    );
}
}

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> polygonContainer</pre>
</div>
<p>&nbsp;</p>
<p>稍微说明一下。</p>
<ul>
<li>getSize 是计算区块大小的方法。这个方法返回一个 size 方法,在 getContainer 方法中输出 JSX 的时候会调用 size 方法得到宽高。</li>
<li>关于布局的问题(为什么写了个双层数组?)之前的文章里写过,不再赘述。</li>
<li>关于数据绑定的机制。通过 props 来绑定。</li>
</ul>
<p>&nbsp;</p>
<p>以上。</p><br><br>
来源:https://www.cnblogs.com/foxcharon/p/11936567.html
頁: [1]
查看完整版本: react实战 : react 与 canvas