react实战 : react 与 svg
<p>有一个需求是这样的。</p><p>一个组件里若干个区块。区块数量不定。</p>
<p>区块里面是一个波浪效果组件,而这个一般用 SVG 做。</p>
<p>所以就变成了在 react 中使用 SVG 的问题。</p>
<p> </p>
<p>首先是波浪效果需要的样式。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">.p{
font</span>-<span style="color: rgba(0, 0, 0, 1)">size: 12px;
line</span>-height: 2<span style="color: rgba(0, 0, 0, 1)">;
text</span>-<span style="color: rgba(0, 0, 0, 1)">align: center;
margin:</span>0<span style="color: rgba(0, 0, 0, 1)">;
width: 52px;
color: #fff;
}
.irrigate_svg {
height: 52px;
width: 52px;
}
.masked {
</span>-webkit-<span style="color: rgba(0, 0, 0, 1)">mask: url(#myMask);
mask: url(#myMask);
}
.irrigate_wrap {
transform: translateY(112px);
}
.irrigate_svg {
overflow: hidden;
}
.irrigate_rate {
animation</span>-<span style="color: rgba(0, 0, 0, 1)">name:wavingleft, wavingUp;
animation</span>-<span style="color: rgba(0, 0, 0, 1)">duration:6s, 6s;
animation</span>-timing-<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">:linear, linear;
animation</span>-iteration-count:infinite, 1<span style="color: rgba(0, 0, 0, 1)">;
}
@keyframes wavingleft {
</span>0%<span style="color: rgba(0, 0, 0, 1)"> {
transform: translateX(</span>-<span style="color: rgba(0, 0, 0, 1)">239px);
}
</span>50%<span style="color: rgba(0, 0, 0, 1)"> {
transform: translateX(0px);
}
</span>100%<span style="color: rgba(0, 0, 0, 1)"> {
transform: translateX(</span>-<span style="color: rgba(0, 0, 0, 1)">239px);
}
}
@keyframes wavingright {
</span>0%<span style="color: rgba(0, 0, 0, 1)"> {
transform: translateX(0px);
}
</span>50%<span style="color: rgba(0, 0, 0, 1)"> {
transform: translateX(</span>-<span style="color: rgba(0, 0, 0, 1)">239px);
}
</span>100%<span style="color: rgba(0, 0, 0, 1)"> {
transform: translateX(0px);
}
}
@keyframes wavingUp{
</span>0%<span style="color: rgba(0, 0, 0, 1)"> {
transform: translateX(</span>-<span style="color: rgba(0, 0, 0, 1)">239px) translateY(100px);
}
</span>50%<span style="color: rgba(0, 0, 0, 1)"> {
transform: translateX(0px);
}
</span>100%<span style="color: rgba(0, 0, 0, 1)"> {
transform: translateX(</span>-<span style="color: rgba(0, 0, 0, 1)">239px) translateY(0px);
}
}</span></pre>
</div>
<p> </p>
<p>引入样式,以及组件文件的结构。</p>
<div class="cnblogs_code">
<pre>import React from 'react'<span style="color: rgba(0, 0, 0, 1)">
import Styles from </span>'./waveContainer.less'<span style="color: rgba(0, 0, 0, 1)">
class Wave extends React.Component {}
class WaveContainer extends React.Component {}
export </span><span style="color: rgba(0, 0, 255, 1)">default</span> WaveContainer</pre>
</div>
<p>一个组件文件里可能有很多层组件,只需要输出最外面的一层。</p>
<p> </p>
<p>SVG 组件。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">class Wave 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)"> {
}
}
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 getNumberPosition </span>= (number) =><span style="color: rgba(0, 0, 0, 1)"> {
let style
const s </span>=<span style="color: rgba(0, 0, 0, 1)"> {
s1:</span>"matrix(1 0 0 1 96.44 150)"<span style="color: rgba(0, 0, 0, 1)">,
s2:</span>"matrix(1 0 0 1 66.44 150)"<span style="color: rgba(0, 0, 0, 1)">,
s3:</span>"matrix(1 0 0 1 46.44 150)"<span style="color: rgba(0, 0, 0, 1)">,
}
</span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (parseInt(number).toString().length) {
</span><span style="color: rgba(0, 0, 255, 1)">case</span> 0<span style="color: rgba(0, 0, 0, 1)">:
style </span>=<span style="color: rgba(0, 0, 0, 1)"> s.s2
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span> 1<span style="color: rgba(0, 0, 0, 1)">:
style </span>=<span style="color: rgba(0, 0, 0, 1)"> s.s1
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span> 2<span style="color: rgba(0, 0, 0, 1)">:
style </span>=<span style="color: rgba(0, 0, 0, 1)"> s.s2
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">case</span> 3<span style="color: rgba(0, 0, 0, 1)">:
style </span>=<span style="color: rgba(0, 0, 0, 1)"> s.s3
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)">:
style </span>=<span style="color: rgba(0, 0, 0, 1)"> s.s2
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> style
}
const getColor </span>= (item) =><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><div >
<div className={Styles.irrigate_svg}>
<svg version="1.1" id="图层_5" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 244.2 244.2" style={{ enableBackground:"new 0 0 244.2 244.2" }} >
<defs>
<mask id="myMask">
<circle style={{ fill:"#fff",stroke:"#fff","strokeMiterlimit":"10" }} cx="122.1" cy="122.1" r="122.1"/>
</mask>
</defs>
<g className={Styles.masked}>
<g className={Styles.irrigate_wrap}><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)"> <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="1120.8899" y1="262.1278" x2="1120.8899" y2="1.81" gradientTransform="matrix(-1 0 0 -1 1430.8899 246)">
<stopoffset="0" style={{ stopColor:getColor(item),"stopOpacity":"0.8" }}/>
<stopoffset="1" style={{ stopColor:getColor(item),"stopOpacity":"0.7"}}/>
</linearGradient> </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">}
</span><path className={Styles.irrigate_rate} style={{ fill:getColor(item) }} d="<span style="color: rgba(0, 0, 0, 1)">M0-3.8c0,0,44.7-14.3,77-12.1c32.9,2.3,95.6,33.3,128.3,31.1c38.9-2.6,116.7-33.7,153-29.7
c22.9,2.5,73,20.4,95.7,24.4c30.9,5.5,64.2,8.4,90.3,6.8C567.8,15.2,620-3.8,620-3.8v248H0V-3.8z</span>"/>
</g>
</g>
<g>
<g id="图层_5-2">
<circle style={{ fill:"none",stroke:"#25437C",strokeWidth:"1",strokeMiterlimit:"1" }} cx="122.1" cy="122.1" r="122.1"/>
<text transform={getNumberPosition(item.data)} style={{ fill:"#FFF", fontSize:"100px" }}> {item.data} </text>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="0" y1="123.91" x2="244.18" y2="123.91" gradientTransform="matrix(1 0 0 -1 0 246)">
<stopoffset="0" style={{ stopColor:"rgb(55,107,112)" }}/>
<stopoffset="1" style={{ stopColor:"rgb(55,107,112)" }}/>
</linearGradient>
<circle style={{ fill:"none",stroke:"url(#SVGID_3_)",strokeWidth:"1",strokeLinecap:"round",strokeMiterlimit:"1" }} cx="122.1" cy="122.1" r="122.1"/>
</g>
</g>
</svg>
</div>
<p className={Styles.p}> {item.name} </p>
</div>
<span style="color: rgba(0, 0, 0, 1)"> );
}
}</span></pre>
</div>
<p> </p>
<p>SVG原本怎么写,JSX就怎么写。</p>
<p>但是遇到了一个问题。</p>
<div><span style="color: rgba(255, 0, 0, 1)">linearGradient</span>, 这个用来做渐变的标签,直接使用没有问题,但如果循环输出的时候把需要的值赋值进去,就会发现所有 SVG 组件的颜色都和第一个一样了。而用开发者工具查看的时候,颜色确实是赋值进去了。不知道是怎么回事。</div>
<div> </div>
<div>然后是容器组件。</div>
<div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">class WaveContainer 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)"> {
}
}
render(){
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)">
}
const theStyle </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)">
}
}
</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, 0, 1)">
const dataBar </span>= (() =><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 && <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: 55, color:'rgb(79,239,223)'<span style="color: rgba(0, 0, 0, 1)"> },
{ name: </span>'a', data: 5, color:'rgb(79,239,223)'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'a', data: 36, color:'rgb(79,239,223)'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'a', data: 476, color:'rgb(87,207,30)'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'a', data: 226, color:'rgb(79,239,223)'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'a', data: 273, color:'rgb(251,211,36)'<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: 124, color:'rgb(79,239,223)'<span style="color: rgba(0, 0, 0, 1)"> },
{ name: </span>'a', data: 253, color:'rgb(79,239,223)'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'a', data: 321, color:'rgb(79,239,223)'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'a', data: 156, color:'rgb(87,207,30)'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'a', data: 2, color:'rgb(79,239,223)'<span style="color: rgba(0, 0, 0, 1)">},
{ name: </span>'a', data: 77, color:'rgb(251,211,36)'<span style="color: rgba(0, 0, 0, 1)">}
]
}
}
}
})()
const Container </span>= ((dataBar) =><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) =>
<div style={theStyle.tem} key={index.toString()}> <Wave data={item} /> </div><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) =>
<div style={theStyle.tem} key={index.toString()}> <Wave data={item} /> </div><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>= <div style={theStyle.shellA} > {temA} </div>
} <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
temShell </span>= .map((item, index) =>
<div style={theStyle.shellB} key={"temShell" + index.toString()}> {index === 0 ? temA : temB} </div>
<span style="color: rgba(0, 0, 0, 1)"> );
theStyle.main.flexWrap </span>= "wrap"<span style="color: rgba(0, 0, 0, 1)">
}
console.log(temShell)
</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)"> (
</span><div style={theStyle.main}><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)"> <Wave /> </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">}
{ Container }
</span></div>
<span style="color: rgba(0, 0, 0, 1)"> );
}
}</span></pre>
</div>
<p> </p>
<p>以上。</p>
</div><br><br>
来源:https://www.cnblogs.com/foxcharon/p/11933649.html
頁:
[1]