Home > Software engineering >  transitioning svg fill image
transitioning svg fill image

Time:10-23

ive got a layout which i use svg since i need 3 triangles that cover the full screen like the image belowenter image description here

when i hover on one of these triangles i want them to change their image, im able to do that, but i want to add a transition effect. the transition works when i only use colors, but when i fill the path with an image the transition effect becomes all flickey basically not working. is there a way to add transitions? or is there a better to way to achieve the same output?

this the code im using now

these are my home triangles

const HomeTriangles=(props)=>{

    return (
      <div >
      <svg width={props.width} height={props.height} className='top-svg'>
         <TopTriangle width={props.width} height={props.height}/>
        <LeftTriangle width={props.width} height={props.height}></LeftTriangle>
        <RightTriangle width={props.width} height={props.height}></RightTriangle>
        </svg>
        
        
     </div>
        
      );

}

and each of these triangles are basically the same, only the paths have different values

const TopTriangle=(props)=>{
    const [hover, setHovered] = useState(false)
  const [textColor, setTextColor] = useState("black")
  const [opacity, setOpacity] = useState(0.5)
  const [stroke, setStroke] = useState("")
  const [strokeWidth, setStrokeWidth] = useState(0)
  const [strokeColor, setStrokeColor] = useState("white")
    return(
        <>
        <defs>
  <pattern id="img1"  x="0" y="0" width="1" height="1">
    <image href={hover?Fishmarket:Test} width={props.width} height={props.height} preserveAspectRatio="xMidYMid slice"


/>
  </pattern>
</defs>
<path
              onm ouseEnter={() => {
                setOpacity(1)
                setStrokeWidth(2)
                setTextColor("black")
                setStrokeColor("white")
                setHovered(true)
            }}
              onm ouseLeave={() => {
                setOpacity(0.5)
                setStrokeWidth(0)
                setTextColor("white")
                setStrokeColor("white")
                setHovered(false)
            }}
            stroke={strokeColor}
            stroke-width={strokeWidth}
              onClick={()=>console.log("clicked")}
              opacity={opacity}
              id="top-triangle"
              fill="url(#img1)"
                d={`M 20 0 L ${props.width/2} ${props.height/2} L ${props.width-20} 0 L 0 0`}
              >

                </path>
              

         
        </>
    )
}

tried looking for other sources help but most were transitions on colors. please help thank you

CodePudding user response:

I'm not sure if this will help you but I recommend taking a look at this framer-motion! package. They have many easy to use animation functions that might help you eliminate a lot of code in your project.

This package helped me animate transitions and elements alike.

I hope this helps you, have a great day.

CodePudding user response:

Here I use CSS transitions to transition from one image (just a blue-colored image) to another (a red-colored image).

So, all images are presents at all times but the blue is covering the red. Now, I don't know how the transition should be, so here are one example for each image.

svg {
  background-color: black;
}

.over1 > image:nth-child(2) {
  opacity: 1;
  transition-property: opacity;
  transition-duration: 1s;
  pointer-events:  visibleFill;
}

.over1:hover > image:nth-child(2) {
  opacity: 0;
}

.over2 > image:nth-child(2) {
  x: 0px;
  transition-property: x;
  transition-duration: 1s;
  pointer-events:  visibleFill;
}

.over2:hover > image:nth-child(2) {
  x: 1000px;
}

.over3 > image:nth-child(2) {
  y: 0px;
  transition-property: y;
  transition-duration: 1s;
  pointer-events:  visibleFill;
}

.over3:hover > image:nth-child(2) {
  y: 300px;
}

.over4 > image:nth-child(2) {
  rotate: 0deg;
  transition-property: rotate;
  transition-duration: 1s;
  pointer-events:  visibleFill;
}

.over4:hover > image:nth-child(2) {
  rotate: 90deg;
}
<svg xmlns="http://www.w3.org/2000/svg" width="500" viewBox="0 0 700 300">
  <defs>
    <clipPath id="lefttriangle">
      <rect width="600" height="600" transform="translate(345 150) rotate(112.2) skewY(45)" />
    </clipPath>
    <clipPath id="righttriangle">
      <rect width="600" height="600" transform="translate(355 150) rotate(-67.8) skewY(45)" fill="white"/>
    </clipPath>
    <clipPath id="toptriangle">
      <rect width="600" height="600" transform="translate(350 145) rotate(-157.8) skewX(-45)" fill="white"/>
    </clipPath>
    <clipPath id="bottomtriangle">
      <rect width="600" height="600" transform="translate(350 155) rotate(22.5) skewX(-45)" fill="white"/>
    </clipPath>
  </defs>
  <g clip-path="url(#lefttriangle)" >
    <image href="https://via.placeholder.com/700/FF0000"/>
    <image href="https://via.placeholder.com/700/0000FF"/>
  </g>
  <g clip-path="url(#righttriangle)" >
    <image href="https://via.placeholder.com/700/FF0000"/>
    <image href="https://via.placeholder.com/700/0000FF"/>
  </g>
  <g clip-path="url(#toptriangle)" >
    <image href="https://via.placeholder.com/700/FF0000"/>
    <image href="https://via.placeholder.com/700/0000FF"/>
  </g>
  <g clip-path="url(#bottomtriangle)" >
    <image href="https://via.placeholder.com/700/FF0000"/>
    <image href="https://via.placeholder.com/700/0000FF"/>
  </g>
</svg>

  • Related