уменьшение масштаба SVG с помощью CSS

#image #svg #zooming #scale

#изображение #svg #масштабирование

Вопрос:

У меня есть этот SVG-файл paperplane, который я хочу разместить внутри круга. Однако, когда я делаю следующее, SVG обрезается по краям. Природа SVG масштабируема, я пытался поработать со свойствами SVG, однако проблема остается. Что я должен сделать, чтобы сохранить этот 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>
  

Это мой HTML и 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>  

Полный файл CSS

   .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%) }
  

Полный файл react — требует тонны рефакторинга, поэтому его трудно читать.

 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
  

Комментарии:

1. Это происходит потому, что вы обрезаете углы svg с помощью border-radius. Я бы поместил изображение внутри div .choice с дополнением. Также ваш svg не является квадратом. Взгляните на viewBox="0 0 18.7 14.3"

2. К сожалению, это сильно испортило бы мою сеточную систему :/

3. В этом случае вам следует поделиться своей «сеточной системой», чтобы получить персонализированный совет

4. Я чувствую некоторую пассивную агрессивность, хотя все в порядке — приближается!

5. А ваш HTML? Не могли бы вы, пожалуйста, добавить свой HTML.

Ответ №1:

Чтобы продемонстрировать оригинальное предложение @exaneta, которое, я не могу себе представить, оказало бы какое-либо влияние на сеточную систему, запустите фрагмент ниже. Если это не то, чего вы пытаетесь достичь, я удалю этот ответ.

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