Search code examples
imagesvgzoomingscale

zooming out of SVG using CSS


I have this SVG of a paperplane, which I want to have inside of a circle. However, when I do the following the SVG is cropped at the edges. The nature of SVG is being scaleable, I have tried fiddling with the properties of the SVG however the problem remains. What should I do to keep this SVG

<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 18.7 14.3" style="enable-background:new 0 0 18.7 14.3;" xml:space="preserve">
<style type="text/css">
    .st0{fill:#000;}
</style>
<path class="st0" d="M18.7,0L0.3,4.1l3,3.6L0,9.4l0.5,4.9l5.6-4.1l2.3,1.5L18.7,0z M1.3,4.4L16,1.2L3.8,7.4L1.3,4.4z M10.3,4.7
    l-9.3,5.5l-0.2,1.7L0.6,9.7L10.3,4.7z M1.2,13.2l0.4-2.7l2.6-1.6l1.5,1L1.2,13.2z M4.7,8.6l12-7.1l-8.3,9.5L4.7,8.6z"/>
</svg>

This is my HTML and CSS

      .choice {
        background-color: #E0D6AF;
        border-radius: 50%;
        height: 200px;
        width: 200px; 
        margin: 10px auto;
        transition:  transform 0.2s;
        transform: scale(1);
        z-index: 10;
      }
 <img id="paper" class="choice" value="paper" src="http://www.jerrylow.com/demo/rps/paper.svg" alt="a piece of paper"> </img>

Full CSS file

  .container {
  display: inline-grid;
  padding-top:30px;
  grid-gap: 2px;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
}

#submit {
  border-radius: 50%;
  height: 150px;
  width: 150px;
  margin: auto;
  grid-column: 2;
  grid-row: 2;
  background-color:#E0D6AF;
}
#submit:hover { 
  transform: scale(1.3);
}
.choice {
  background-color: #E0D6AF;
  border-radius: 50%;
  height: 200px;
  width: 200px; 
  margin: 10px auto;
  transition:  transform 0.2s;
  transform: scale(1);
  z-index: 10;
}
      .choice > img:hover {
        transform: scale(1.1);
      }
      #rock{
      grid-column: 1;
      grid-row:1;
      }
      #paper{
        grid-column: 1;
        grid-row:2;
      }
      #scissor{
        grid-column: 1;
        grid-row:3;
      }

      #humanScore > p {
        padding-top: 80px;
        text-align: center !important;
      }
      #humanScore {
        grid-column: 2;
        grid-row: 3;  
      }
      #computerScore > p {
        padding-top: 80px;
        text-align: center !important;
      }
      #computerScore {
        grid-column: 2;
        grid-row: 1; 
      }

      #result {
        margin: auto;
        width: 150px;
        height: 150px;
        border-radius: 50%;
        grid-column: 3;
        grid-row: 2;
      } 

      @keyframes pulse{
        0%{
          transform: scale(0);
        }
        100%{
          transform: scale(1);
        }
      }

      .resultWin{
        background-color:lightgreen;
        transition:  transform 0.2s;
        transform: scale(1.3);
        animation-name: pulse;
        animation-duration: 1s;
        animation-iteration-count: 1;
        animation-fill-mode: both;

      }  
      .resultLoss{
        background-color: crimson;
        transition:  transform 0.2s;
        transform: scale(1.3);
        animation-name: pulse;
        animation-duration: 1s;
        animation-iteration-count: 1;
        animation-fill-mode: both;

      } 
      .resultTie{
        background-color:goldenrod;
        transition:  transform 0.2s;
        transform: scale(1.3);
        animation-name: pulse;
        animation-duration: 1s;
        animation-iteration-count: 1;
        animation-fill-mode: both;
      } 
      .chosen { filter: brightness(70%) }

Full react file - needs a ton of refactoring so difficult to read.

import React from 'react';
import './Game.css'

class Game extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      picked: '',
      score: {
        player: 0,
        computer: 0
      },
      previousPicks: {
        rock: 0,
        scissor: 0,
        paper: 0
      },
      result: { result: "", player: "", computer: "" }
    };
  }

  unmarkImage = () => {
    if (this.state.picked !== "") {
      document.querySelector(`#${this.state.picked}`).classList.remove("chosen")
    }
  }

  onClickHandler = (event) => {
    this.unmarkImage();
    document.querySelector(`#${event.target.attributes.value.value}`).classList.add("chosen");
    this.setState({ picked: event.target.attributes.value.value });
  }

  onSubmit = () => {
    if (this.state.picked === "") {
      alert("pick your weapon, before fighting")
      return
    }
    const self = this;
    fetch(`/api/play/${this.state.picked}`)
      .then(function (res) {
        res.text().then((function (text) {
          self.setState({ result: JSON.parse('{' + text.replace(/(\w+):(\w+)/g, `"$1":"$2"`) + '}') })
          self.updateScore(self.state.result.result);
          self.updateResult();
          self.unmarkImage();
          self.updateComputerChoice();
          self.updatePreviousPicks(self.state.picked)
          self.setState({ picked: "" })
        }))
      })
  }

  updateScore = (result) => {
    let scoreClone = { ...this.state.score }
    if (result === "win") {
      scoreClone.player++
      this.setState({
        score: scoreClone
      })
    } else if (result === "loss") {
      scoreClone.computer++
      this.setState({
        score: scoreClone
      })
    }
  }
  updatePreviousPicks = (pick) => {
    let previousPicksClone = { ...this.state.previousPicks }
    if (pick === "rock") {
      previousPicksClone.rock++;
      this.setState({
        previousPicks: previousPicksClone
      })
    } else if (pick === "scissor") {
      previousPicksClone.scissor++;
      this.setState({
        previousPicks: previousPicksClone
      })
    } else {
      previousPicksClone.paper++;
      this.setState({
        previousPicks: previousPicksClone
      })
    }
  }

  onReset = () => { //looks clumsy, but good performance
    let computerDiv = document.querySelector("#computer")
    while (computerDiv.firstChild) {
      computerDiv.removeChild(computerDiv.firstChild);
    }
  }

  updateResult = () => {
    let result = document.querySelector("#result")
    if (this.state.result.result === "win") {
      result.classList.add("resultWin");
    }
    else if (this.state.result.result === "loss") {
      result.classList.add("resultLoss");
    } else {
      result.classList.add("resultTie");
    }
  }

  updateComputerChoice = () => {
    let computerChoice = this.state.result.computer;
    let result = document.querySelector("#result");
    while (result.firstChild) {
      result.removeChild(result.firstChild);
    }
    let answer = document.createElement("img");
    let img;
    if (computerChoice === "rock") {
      img = document.getElementById("rock").src;
    } else if (computerChoice === "scissor") {
      img = document.getElementById("scissor").src;
    } else {
      img = document.getElementById("paper").src;
    }
    answer.src = img;
    result.appendChild(answer);
  }

  render() {
    return (
      <div className="container">
        <img id="rock" className="choice" value="rock" src="resources/rock.svg" alt="a rock" onClick={this.onClickHandler}></img>
        <img id="paper" className="choice" value="paper" src="resources/paper.svg" alt="a piece of paper" onClick={this.onClickHandler}></img>
        <img id="scissor" className="choice" value="scissor" src="resources/scissor.svg" alt="a scissor" onClick={this.onClickHandler}></img>
        <button id="submit" className="waves-effect waves-light btn" onClick={this.onSubmit}>Fight the AI!</button>
        <div id="humanScore">
          <p>You: {this.state.score.player}</p>
        </div>
        <div id="computerScore">
          <p>Computer: {this.state.score.computer}</p>
        </div>
        <div id="result" className="">
        </div>
      </div>
    )
  }
}

export default Game

Solution

  • To demonstrate @enxaneta 's original suggestion, which I can't imagine would have any effect on a grid system, run the snippet below. If that's not what you are trying to accomplish, I'll delete this answer.

    .choice {
        background-color: #E0D6AF;
        border-radius: 50%;
        height: 200px;
        width: 200px; 
        margin: 10px auto;
        transition:  transform 0.2s;
        transform: scale(1);
        z-index: 10;
        display: flex;
        justify-content: center;
        align-items: center;
      }
     .choice > img#paper{
        width: 60%;
     }
    <div class="choice">
      <img 
        id="paper" 
        value="paper"   
        src="http://www.jerrylow.com/demo/rps/paper.svg" 
        alt="a piece of paper"
       />
    </div>