Placing a play button on an svg

How would I do this?

<svg width="180" height="180">

<circle cx="90" cy="90" r="85" fill="orange" />

 
<image width="180" height="180" xlink:href="http://i.imgur.com/4HJbzEq.png" />

 </svg>





<style>
  #playButton2 {
    width: 180px;
    height: 180px;
    cursor: pointer;
    border: 1px solid #0059dd;
 
 
   }


  #playButton2 div:hover {
    border-radius: 50%;
    border: 1px solid red;
  }
  
  .initial {
    width: 36px;
    height: 36px;
    margin: 20px 20px;
    background-color: rgba(0, 0, 0, .7);
    background-image: url('https://i.imgur.com/Lj57czy.png');
    background-size: 14px 18px;
    background-repeat: no-repeat;
    background-position: 58% 45%;
    border-radius: 50%;
    border: 1px solid white;
  }
  
  .pause {
    display: none;
    width: 36px;
    height: 36px;
    margin: 20px 20px;
    background-color: rgba(0, 0, 0, .7);
    background-image: url('https://i.imgur.com/LgmfKda.png');
    background-repeat: no-repeat;
    background-size: 14px 18px;
    background-position: 50%;
    border-radius: 500px;
    border: 1px solid white;
  }

  .play {
    display: none;
    width: 36px;
    height: 36px;
    margin: 20px 20px;
    background-color: rgba(0, 0, 0, .7);
    background-image: url('https://i.imgur.com/Lj57czy.png');
    background-size: 14px 18px;
    background-repeat: no-repeat;
    background-position: 58% 45%;
    border-radius: 50%;
    border: 1px solid white;
  }

</style>

<div id="playButton2" onclick=" 
var button = document.getElementById('playButton2');
var player = document.getElementById('player2');
  document.querySelector('#playButton2 .initial').style.display='none';
  document.querySelector('#playButton2 .pause').style.display='none';
  document.querySelector('#playButton2 .play').style.display='none';
player.volume=1.0; if (player.paused) {
document.querySelector('#playButton2 .pause').style.display='inline-block';
player.play();
} else {
document.querySelector('#playButton2 .play').style.display='inline-block';
player.pause();
}">

  <div class="initial"> </div>

  <div class="pause"> </div>

  <div class="play"> </div>


</div>

<audio id="player2" style="display:none;">
  <source src='http://hi5.1980s.fm/;' type='audio/mpeg'></source>
</audio>

It looks like you’ve done it.

As I see several possible things that might usefully be done with this, would you care to explain what you want to achieve?

I’ll make an assumption that you want the icons in the centre of the wheel.

You can put the svg inside of the play button, and set the svg position to be absolute, which removes it from the normal flow allowing other things to flow over the top of it, such as the buttons.

First, move the svg image that you intend for the background, inside of the play button.

<div id="playButton2" onclick="..." ...>
    <svg width="180" height="180">
      <circle cx="90" cy="90" r="85" fill="orange" />
      <image width="180" height="180" xlink:href="http://i.imgur.com/4HJbzEq.png" />
    </svg>

    <div class="initial"> </div>
    <div class="pause"> </div>
    <div class="play"> </div>
</div> 

Give the svg a meaningful name:

<svg class="background" width="180" height="180">

use relative/absolute on the play button and background

  #playButton2 {
    ...
    position: relative;
  }
  #playButton2 .background {
    position: absolute;
    z-index: -1;
  }

The -1 z-index pushes the svg to the back, allowing everything else to show in front of it.

That’s it working, and the rest of this is removing unwanted duplication from the icons.

We can wrap the icons with a button div, so that presentation effects that are common to the icons can all happen on their surrounding div.

Here’s the wrapped icons:

<div class="button">
    <div class="initial"> </div>
    <div class="pause"> </div>
    <div class="play"> </div>
</div>

That breaks the background red circle, so update the hover class to target the icons.

  /* #playButton2 .button:hover { */
  .button div:hover {
    border: 1px solid red;
  }

and hovering on the icons correctly changes the background red circle now.

We can now moving all of the duplicate class declarations to a new definition for their surrounding div.

  .button div {
    width: 36px;
    height: 36px;
    margin: 69px 71px;
    background-color: rgba(0, 0, 0, .7);
    background-size: 14px 18px;
    background-repeat: no-repeat;
    border-radius: 50%;
    border: 1px solid white;
  } 

Which leaves the icons with only the things by which they are different.

  .initial {
    background-image: url('https://i.imgur.com/Lj57czy.png');
    background-position: 58% 45%;
  }
  .pause {
    background-image: url('https://i.imgur.com/LgmfKda.png');
    background-position: 50%;
    display: none;
  }
  .play {
    background-image: url('https://i.imgur.com/Lj57czy.png');
    background-position: 58% 45%;
    display: none;
  }

Here’s the end result: https://jsfiddle.net/v63adot5/3/

2 Likes

One of the important ideas is to reduce how much work you need to do when change occurs.

For example, when the playButton2 element is renamed, how much of the rest of the code needs to change because of that?

Currently the scripts that have lots of references to playButton2

var button = document.getElementById('playButton2');
...
document.querySelector('#playButton2 .initial').style.display='none';
document.querySelector('#playButton2 .pause').style.display='none';
document.querySelector('#playButton2 .play').style.display='none';
...
document.querySelector('#playButton2 .pause').style.display='inline-block';
...
document.querySelector('#playButton2 .play').style.display='inline-block';

All of those references to playButton2 become a ball-and-chain holding you back, because to make an adjustment somewhere means making a lot of adjustments all over the place.

This problem can be easily dealt with by saving a reference to playButton2 to a variable, so that we can start from that variable instead in the code. That way, only one place in the code needs to be changed.

var button = document.getElementById('playButton2');
...
button.querySelector('.initial').style.display='none';
button.querySelector('.pause').style.display='none';
button.querySelector('.play').style.display='none';
...
button.querySelector('.pause').style.display='inline-block';
...
button.querySelector('.play').style.display='inline-block';

It is now easier to make changes to the playButton2 name, and this helps to get the code ready for if you have multiple play buttons too. You can give the button name to a function, and the code in the function will happily do what’s needed based on that name.

The updated code with this simple but effective change is at https://jsfiddle.net/v63adot5/4/

Got it, thanks.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.