0

I have used the wheel of fortune code from how to draw a wheel of fortune?

I've modified function drawSector(sector,i) to drawImage on each sector like this:

function drawSector(sector, i) {
        const ang = arc * i;
        ctx.save();
        // COLOR
        ctx.beginPath();
        ctx.fillStyle = sector.color;
        ctx.moveTo(rad, rad);
        ctx.arc(rad, rad, rad, ang, ang + arc);
        ctx.lineTo(rad, rad);
        ctx.fill();
        // TEXT
        ctx.translate(rad, rad);
        ctx.rotate(ang + arc / 2);
        if(!sector.label.includes('<img')){
            ctx.textAlign = "right";
            ctx.fillStyle = "#fff";
            ctx.fillText(sector.label, rad-10, txtPositionY);
        }     
        else{
            // IMG
            const div = document.createElement('div')
                          div.innerHTML = sector.label
                  const img = div.querySelector('img');
                  const ratio = img.width/img.height;

                  let imgMinH = (2*PI*55)/sectors.length; // // r=110/2
                  let imgMaxW = (rad-15) - 55;
                  let imgW    = imgMinH*ratio; 
                  let imgH    = imgMinH;
                  let imgX = (rad-15)-imgW;
                  let imgY = (-imgH)/2;         
                  let LX   =    (2*PI*imgX)/sectors.length; 

                  if(imgW<imgMaxW){
                      while( (imgX>55) && (imgH<LX) && (imgW<imgMaxW) ){
                        imgW += 1;
                        imgH = imgW/ratio;
                        imgX = (rad-15)-imgW;
                        imgY = (-imgH)/2;   
                        LX   =  (2*PI*imgX)/sectors.length; 
                      } 
                  }
                  else{
                    while( (imgX<55) || (imgH>LX) || (imgW>imgMaxW) ){
                        imgW -= 1;
                        imgH = imgW/ratio;
                        imgX = (rad-15)-imgW;
                        imgY = (-imgH)/2;   
                        LX   =  (2*PI*imgX)/sectors.length; 
                      } 
                  }

                  console.log("ratio:"+ratio+'\n orgH:'+imgMinH+'\n imgW:'+imgW+'\nimgH:'+imgH+'\nLX:'+LX+'\nimgX:'+imgX+'\nimgY:'+imgY+'\nimgMaxW:'+imgMaxW);
            ctx.drawImage(img, imgX, imgY, imgW, imgH);
        }   
        ctx.restore();
      };

but i can not calculate exactly about image width, height and position. Please see the images below:

Currently

How to calculate exactly image width, height, position to drawImage like this image below?

this is what i want

Thank you!

Duc Manh Nguyen
  • 768
  • 2
  • 8
  • 13

1 Answers1

1

const button = document.querySelector('.ring__button');
const ring = document.querySelector('.ring__wrapper');

button.addEventListener('click', () => {
    ring.classList.add('ring__wrapper--rotate')
})
:root {
    --size: 300px;
}
.ring {
    width: var(--size);
    height: var(--size);
    position: relative;
    z-index: 1;
}

.ring__wrapper {
    display: flex;
    flex-wrap: wrap;
    border-radius: 100%;
    overflow: hidden;
    transform-origin: 50% 50%;
    position: relative;
    width: inherit;
    height: inherit;
}

.ring__wrapper--rotate {
    animation: rotate 3s;
    transform: rotate(990deg)
}

.ring__button {
    position: absolute;
    z-index: 1;
    border: none;
    width: calc(var(--size) / 3);
    height: calc(var(--size) / 3);
    border-radius: 100%;
    background: red;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #ffffff;
    font-weight: bold;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

.ring__button:after {
    position: absolute;
    z-index: 3;
    display: block;
    content: '';
    left: 50%;
    bottom: 100%;
    border-bottom: 20px solid red;
    border-left: 10px solid transparent;
    border-right: 10px solid transparent;
    transform: translate(-50%, 5%);
}

.ring__part {
    width: calc(var(--size) / 2);
    height: var(--size);
    overflow: hidden;
}

.ring__part img {
    width: inherit;
    height: inherit;
    object-fit: contain;
}

.ring__part--1 {background: aquamarine;}
.ring__part--1 img {transform: rotate(180deg);}

.ring__part--2 {background: antiquewhite;}

@keyframes rotate {
    from {transform: rotate(0)}
    to {transform: rotate(990deg)}
}
<div class="ring">
    <button class="ring__button">QUAY</button>
    <div class="ring__wrapper">
        <div class="ring__part ring__part--1"><img src="https://images.unsplash.com/photo-1655810120657-9ce44d2f9e6c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxOXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt=""></div>
        <div class="ring__part ring__part--2"><img src="https://images.unsplash.com/photo-1655810120657-9ce44d2f9e6c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxOXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt=""></div>
    </div>
</div>

canvas is cool, but what about css?

const button = document.querySelector('.ring__button');
const ring = document.querySelector('.ring__wrapper');

button.addEventListener('click', () => {
    ring.classList.add('ring__wrapper--rotate')
})
:root {
        --size: 300px;
    }
    .ring {
        width: var(--size);
        height: var(--size);
        position: relative;
        z-index: 1;
    }

    .ring__wrapper {
        display: flex;
        flex-wrap: wrap;
        border-radius: 100%;
        overflow: hidden;
        transform-origin: 50% 50%;
        position: relative;
        width: inherit;
        height: inherit;
    }

    .ring__wrapper--rotate {
        animation: rotate 3s;
        transform: rotate(855deg)
    }

    .ring__button {
        position: absolute;
        z-index: 1;
        border: none;
        width: calc(var(--size) / 3);
        height: calc(var(--size) / 3);
        border-radius: 100%;
        background: red;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #ffffff;
        font-weight: bold;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
    }

    .ring__button:after {
        position: absolute;
        z-index: 3;
        display: block;
        content: '';
        left: 50%;
        bottom: 100%;
        border-bottom: 20px solid red;
        border-left: 10px solid transparent;
        border-right: 10px solid transparent;
        transform: translate(-50%, 5%);
    }

    .ring__part {
        width: calc(var(--size) / 2);
        height: calc(var(--size) / 2);
        overflow: hidden;
    }

    .ring__part img {
        width: inherit;
        height: inherit;
        object-fit: contain;
    }

    .ring__part--1 {background: aquamarine;}
    .ring__part--1 img {transform: rotate(225deg);}

    .ring__part--2 {background: antiquewhite;}
    .ring__part--2 img {transform: rotate(-45deg);}

    .ring__part--3 {background: brown;}
    .ring__part--3 img {transform: rotate(135deg);}

    .ring__part--4 {background: burlywood;}
    .ring__part--4   img {transform: rotate(45deg);}

    @keyframes rotate {
        from {transform: rotate(0)}
        to {transform: rotate(855deg)}
    }
<div class="ring">
<button class="ring__button">QUAY</button>
    <div class="ring__wrapper">
        <div class="ring__part ring__part--1"><img src="https://images.unsplash.com/photo-1655810120657-9ce44d2f9e6c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxOXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt=""></div>
        <div class="ring__part ring__part--2"><img src="https://images.unsplash.com/photo-1655810120657-9ce44d2f9e6c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxOXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt=""></div>
        <div class="ring__part ring__part--3"><img src="https://images.unsplash.com/photo-1655810120657-9ce44d2f9e6c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxOXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt=""></div>
        <div class="ring__part ring__part--4"><img src="https://images.unsplash.com/photo-1655810120657-9ce44d2f9e6c?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwxOXx8fGVufDB8fHx8&auto=format&fit=crop&w=800&q=60" alt=""></div>
    </div>
</div>
Pete Pearl
  • 341
  • 1
  • 6
  • This is a good idea to create wheel of fortune. But it's not resolve my problem. Because i want to create more function such as: show result in popup, remove result, sound effect,... Please see my current website https://dichthuatphuongdong.com/tienich/random-name-picker.html (currently without image on wheel). Sorry, my website contain google ads. – Duc Manh Nguyen Jun 22 '22 at 10:49