React Native 如何在动画圆圈的头部添加边框和阴影(或标记)?

myss37ts  于 2023-11-21  发布在  React
关注(0)|答案(1)|浏览(133)

所以我使用了这个component,我试图找出一种方法,当它溢出(超过100%)时,使环与自身重叠,但要表明我们需要一个边框和阴影,无论动画环的头部在哪里。我已经将代码转换为JavaScript,所以我们需要在React Native的JavaScript中这样做。

<Svg
      width={scaledWidth}
      height={scaledHeight}
      viewBox={viewBox}
      style={{ position: "absolute" }}
    >
      <Defs>
        <LinearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
          <Stop offset="0%" stopColor={gradientEndColor} />
          <Stop offset="100%" stopColor={gradientStartColor} />
        </LinearGradient>
      </Defs>
      <G rotation={-90} originX="90" originY="90">
        <Circle
          cx="50%"
          cy="50%"
          r={radius + 5} 
          stroke="black" 
          fill="transparent"
          strokeWidth={11}
        />
        <Circle
          cx="50%"
          cy="50%"
          r={radius}
          stroke={bgColor}
          fill="transparent"
          strokeWidth="19"
        />
        <AnimatedCircle
          cx="50%"
          cy="50%"
          r={radius}
          stroke="url(#gradient)"
          fill="transparent"
          strokeWidth="19"
          strokeDasharray={circleCircumference}
          strokeDashoffset={strokeDashoffset}
          strokeLinecap="round"
        />
      </G>
      {customIcon(radius)}
    </Svg>

字符串
我试过做一个圆,它可以创建一个球,并跟随动画圆的结尾,但不知道如何做到这一点。我也试过为strokeLinecap创建一个标记,但我认为它不支持。
基本上,我试图让这个功能完全像苹果活动戒指的手表。任何帮助将不胜感激。

cyvaqqii

cyvaqqii1#

在这种情况下,没有花哨的解决方案,它只是努力工作,使其接缝,圆圈重叠本身。
在该示例中(对于每个圆/米)每个都由三个圆组成。中间的一个是米本身。笔划破折号数组改变值,直到它是一个完整的圆。从那里开始,圆只是旋转。为了使它看起来米本身重叠,在米下面和米上面有一个圆。它们具有相同的颜色,所以它看起来它们是一个,它们是一体的,米出现在顶部圆圈的梯度下。
为了使投影只出现在 Jmeter 的“前面”,有一个比 Jmeter 长一点的圆形遮罩。

document.forms.form01.addEventListener('change', e => {
  let newval = parseInt(e.target.value);
  let rotateAll = (newval > 360) ? newval - 360 : 0;
  let rotateMask = (newval > 180) ? newval + 90 : -90;
  rotateMask = (newval > 270) ? 0 : rotateMask;
  let rotateMeter = (newval > 240) ? 45 : 0;

  let circle = document.getElementById(`circle${e.target.name}`);
  let maskcircle = document.querySelector(`#mask${e.target.name} circle`);

  circle.querySelector('.meter').setAttribute('stroke-dasharray', `${newval - rotateAll - rotateMeter} 360`);
  maskcircle.setAttribute('stroke-dasharray', `${newval+5} 360`);
  circle.setAttribute('transform', `rotate(${rotateAll})`);
  circle.querySelector('.under').setAttribute('transform', `rotate(${rotateMask})`);
  circle.querySelector('.over').setAttribute('transform', `rotate(${rotateMask})`);
  circle.querySelector('.meter').setAttribute('transform', `rotate(${rotateMeter})`);
});
body {
  background-color: #111;
  display: flex;
  color: white;
}

form {
  display: flex;
  flex-direction: column;
}

lable {
  display: flex;
  justify-content: space-between;
}
<form name="form01">
  <lable>Red: <input name="red" type="range" min="0" max="720" value="20" /></lable>
  <lable>Green: <input name="green" type="range" min="0" max="720" value="20" /></lable>
  <lable>Blue: <input name="blue" type="range" min="0" max="720" value="20" /></lable>
</form>
<svg height="95vh" viewBox="0 0 100 100" fill="none" stroke-width="11.5" stroke-linecap="round">
  <defs>
    <filter id="shadow" x="-50" y="-50" filterUnits="userSpaceOnUse">
      <feDropShadow dx="0" dy="0" stdDeviation="1" />
    </filter>
    <linearGradient id="lg01" gradientTransform="rotate(90)">
      <stop offset="50%" stop-color="white" />
      <stop offset="90%" stop-color="black" />
    </linearGradient>
    <mask id="maskred">
      <circle stroke="white" r="44" pathLength="360" stroke-dasharray="25 360"/>
    </mask>
    <mask id="maskgreen">
      <circle stroke="white" r="32" pathLength="360" stroke-dasharray="25 360"/>
    </mask>
    <mask id="maskblue" x="-60" y="-60" width="200" height="200" maskUnits="userSpaceOnUse">
      <circle stroke="white" r="20" pathLength="360" stroke-dasharray="25 360"/>
    </mask>
    <mask id="mask04">
      <rect transform="translate(10 -15) rotate(35)" fill="url(#lg01)" width="50" height="55"/>
    </mask>
    <mask id="mask05">
      <rect transform="translate(10 -15) rotate(35)" fill="url(#lg01)" width="50" height="45"/>
    </mask>
    <mask id="mask06">
      <rect transform="translate(10 -15) rotate(35)" fill="url(#lg01)" width="50" height="38"/>
    </mask>
  </defs>
  
  <g transform="translate(50 50) rotate(-90)">
    <circle stroke="Tomato" r="44" opacity=".4" />
    <circle stroke="MediumSeaGreen" r="32" opacity=".4" />
    <circle stroke="SkyBlue" r="20" opacity=".4" />
    <g id="circlered" mask="url(#maskred)">
      <circle class="under" transform="rotate(-90)" stroke="red" r="44" pathLength="360" stroke-dasharray="15 360"/>
      <circle class="meter" stroke="Tomato" filter="url(#shadow)" r="44" pathLength="360" stroke-dasharray="20 360" />
      <circle class="over" transform="rotate(-90)" mask="url(#mask04)" stroke="red" r="44" pathLength="360" stroke-dasharray="55 360" stroke-dashoffset="-19" />
    </g>
    <g id="circlegreen" mask="url(#maskgreen)">
      <circle class="under" transform="rotate(-90)" stroke="ForestGreen" r="32" pathLength="360" stroke-dasharray="20 360"/>
      <circle class="meter" stroke="MediumSeaGreen" filter="url(#shadow)"  r="32" pathLength="360" stroke-dasharray="20 360" />
      <circle class="over" transform="rotate(-90)" mask="url(#mask05)" stroke="ForestGreen" r="32" pathLength="360" stroke-dasharray="55 360" stroke-dashoffset="-25" />
    </g>
    <g id="circleblue" mask="url(#maskblue)">
      <circle class="under" transform="rotate(-90)" stroke="DodgerBlue" r="20" pathLength="360" stroke-dasharray="28 360"/>
      <circle class="meter" stroke="SkyBlue" filter="url(#shadow)" r="20" pathLength="360" stroke-dasharray="20 360" />
      <circle class="over" transform="rotate(-90)" mask="url(#mask06)" stroke="DodgerBlue" r="20" pathLength="360" stroke-dasharray="55 360" stroke-dashoffset="-38" />
    </g>  
</svg>

相关问题