react实战 : react 与 svg

react

有一个需求是这样的。

一个组件里若干个区块。区块数量不定。

区块里面是一个波浪效果组件,而这个一般用 SVG 做。

所以就变成了在 react 中使用 SVG 的问题。

首先是波浪效果需要的样式。

.p{

font-size: 12px;

line-height: 2;

text-align: center;

margin:0;

width: 52px;

color: #fff;

}

.irrigate_svg {

height: 52px;

width: 52px;

}

.masked {

-webkit-mask: url(#myMask);

mask: url(#myMask);

}

.irrigate_wrap {

transform: translateY(112px);

}

.irrigate_svg {

overflow: hidden;

}

.irrigate_rate {

animation-name:wavingleft, wavingUp;

animation-duration:6s, 6s;

animation-timing-function:linear, linear;

animation-iteration-count:infinite, 1;

}

@keyframes wavingleft {

0% {

transform: translateX(-239px);

}

50% {

transform: translateX(0px);

}

100% {

transform: translateX(-239px);

}

}

@keyframes wavingright {

0% {

transform: translateX(0px);

}

50% {

transform: translateX(-239px);

}

100% {

transform: translateX(0px);

}

}

@keyframes wavingUp{

0% {

transform: translateX(-239px) translateY(100px);

}

50% {

transform: translateX(0px);

}

100% {

transform: translateX(-239px) translateY(0px);

}

}

引入样式,以及组件文件的结构。

import React from 'react'

import Styles from './waveContainer.less'

class Wave extends React.Component {}

class WaveContainer extends React.Component {}

export default WaveContainer

一个组件文件里可能有很多层组件,只需要输出最外面的一层。

SVG 组件。

class Wave extends React.Component {

constructor(props){

super(props)

this.state = {

}

}

render(){

const item = this.props.data

const getNumberPosition = (number) => {

let style

const s = {

s1:"matrix(1 0 0 1 96.44 150)",

s2:"matrix(1 0 0 1 66.44 150)",

s3:"matrix(1 0 0 1 46.44 150)",

}

switch (parseInt(number).toString().length) {

case 0:

style = s.s2

break;

case 1:

style = s.s1

break;

case 2:

style = s.s2

break;

case 3:

style = s.s3

break;

default:

style = s.s2

}

return style

}

const getColor = (item) => {

return item.color

}

return (

<div >

<div className={Styles.irrigate_svg}>

<svg version="1.1" }} >

<defs>

<mask >

<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}>

{/* <linearGradient >

<stop offset="0" style={{ stopColor:getColor(item),"stopOpacity":"0.8" }}/>

<stop offset="1" style={{ stopColor:getColor(item),"stopOpacity":"0.7"}}/>

</linearGradient> */}

<path className={Styles.irrigate_rate} style={{ fill:getColor(item) }} d="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"/>

</g>

</g>

<g>

<g >

<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 >

<stop offset="0" style={{ stopColor:"rgb(55,107,112)" }}/>

<stop offset="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>

);

}

}

SVG原本怎么写,JSX就怎么写。

但是遇到了一个问题。

linearGradient, 这个用来做渐变的标签,直接使用没有问题,但如果循环输出的时候把需要的值赋值进去,就会发现所有 SVG 组件的颜色都和第一个一样了。而用开发者工具查看的时候,颜色确实是赋值进去了。不知道是怎么回事。

 

然后是容器组件。

class WaveContainer extends React.Component {

constructor(props){

super(props)

this.state = {

}

}

render(){

const baseFlex = {

display: 'flex',

justifyContent: 'center',

alignItems: 'center'

}

const theStyle = {

main:{

...baseFlex,

width:'100%',

height:'100%',

color:"#fff"

},

tem:{

...baseFlex,

flex:"auto",

color:'#fff'

},

shellA:{

...baseFlex,

width:'100%',

height:'100%'

},

shellB:{

...baseFlex,

width:'100%',

height:'50%'

}

}

// const dataBar = this.props.dataBar

const dataBar = (() => {

if (this.props.curcity && this.props.curcity === 'all') {

return {

data:{

sData:[

{ name: 'a', data: 55, color:'rgb(79,239,223)' },

{ name: 'a', data: 5, color:'rgb(79,239,223)'},

{ name: 'a', data: 36, color:'rgb(79,239,223)'},

{ name: 'a', data: 476, color:'rgb(87,207,30)'},

{ name: 'a', data: 226, color:'rgb(79,239,223)'},

{ name: 'a', data: 273, color:'rgb(251,211,36)'}

]

}

}

} else {

return {

data:{

sData:[

{ name: 'a', data: 124, color:'rgb(79,239,223)' },

{ name: 'a', data: 253, color:'rgb(79,239,223)'},

{ name: 'a', data: 321, color:'rgb(79,239,223)'},

{ name: 'a', data: 156, color:'rgb(87,207,30)'},

{ name: 'a', data: 2, color:'rgb(79,239,223)'},

{ name: 'a', data: 77, color:'rgb(251,211,36)'}

]

}

}

}

})()

const Container = ((dataBar) => {

const flexMatrix = [

[0,0],

[1,0],

[2,0],

[3,0],

[2,2],

[3,2],

[3,3],

[4,3],

[4,4],

[5,4],

[5,5],

[6,5],

[6,6]

]

const sData = dataBar.data.sData

const length = sData.length

const matrix = flexMatrix[length] ? flexMatrix[length] : flexMatrix[12]

if (matrix[0] === 0) {

return ""

}

let temShell, temA, temB

temA = sData.slice(0, matrix[0]).map((item, index) =>

<div style={theStyle.tem} key={index.toString()}> <Wave data={item} /> </div>

);

if (matrix[1] === 0) {

temB = ""

} else {

temB = sData.slice(matrix[0], (matrix[0] + matrix[1])).map((item, index) =>

<div style={theStyle.tem} key={index.toString()}> <Wave data={item} /> </div>

);

}

if (matrix[1] === 0) {

temShell = <div style={theStyle.shellA} > {temA} </div>

} else {

temShell = [0,0].map((item, index) =>

<div style={theStyle.shellB} key={"temShell" + index.toString()}> {index === 0 ? temA : temB} </div>

);

theStyle.main.flexWrap = "wrap"

}

console.log(temShell)

return temShell

})(dataBar)

return (

<div style={theStyle.main}>

{/* <Wave /> */}

{ Container }

</div>

);

}

}

以上。

以上是 react实战 : react 与 svg 的全部内容, 来源链接: utcz.com/z/381394.html

回到顶部