好久沒有寫太小組件了,忽然想作一個抽獎轉盤,就花半天時間作一個,很簡單css
1.支持把一個圓盤分紅n瓣。
2.實現轉動動畫。
3.弄個指針樣式意思意思。
4.遇到抽獎的需求改吧改吧就能用了。react
圖是這樣的web
過度中分析的問題:
1.怎樣根據數組長度把分好的扇形角度旋轉到合適的位置。
2.扇形內部的元素也會跟着旋轉,怎麼矯正。數組
樣式dom
@keyframes circle{ from {transform: rotate(0)} to {transform: rotate(720deg)} } .turntable{ height: 400px; width: 400px; margin: 0 auto; position: relative; } .content{ height: 400px; width: 400px; position: relative; background-color: rgba(0, 0, 0, 0.3); border-radius: 50%; overflow: hidden; animation: circle 3s infinite; -webkit-animation:circle 3s infinite; /*Safari and Chrome*/ } .box { height: 400px; width: 400px; position: absolute; left: 0; right: 0; } .item{ position: absolute; height: 200px; width: 200px; left: 50%; top: 0; color: #fff; } .info{ position: absolute; left: 5%; top: 50%; } .point{ position: absolute; left: 50%; top: 50%; width: 30px; height: 30px; background-color: #ffd81a; border: 2px solid #ed1212; transform: translate(-50%, -50%); border-radius: 50%; } .arrow{ position: absolute; left: 50%; top: 50%; height: 100px; width: 16px; transform: translate(-50%, -50%); background-color: #ffd81a; margin: -50px auto 0; box-shadow: 0px 0px 18px #7a7070; } .arrow::after{ content: ' '; position: absolute; border-top: 8px solid transparent; border-left: 8px solid transparent; border-right: 8px solid transparent; border-bottom: 20px solid #ffd81a; top: -28px; left: 0px; }
邏輯動畫
import React from 'react'; import styles from './index.css'; import yay from '../assets/yay.jpg' const gift: any[] = [ { name: '1', }, { name: '2' }, { name: '3' }, { name: '4' }, { name: '5', }, { name: '6' }, { name: '7' }, { name: '8' }, { name: '9' }, { name: '10' }, ] function getColor(): string { let colorValue = '0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f' let colorArray: string[] = colorValue.split(",") let color: string = '#' for (let i: number = 0; i < 6; i++) { color += colorArray[Math.floor(Math.random() * 16)] } return color } interface itemStyle { transform: string; backgroundColor: string; } function get_skew_deg(num: number): number { let average_deg: number = 360 / num let skew_deg: number = 90 - average_deg return skew_deg } function getItemStyle(num: number): itemStyle { let skew_deg: number = get_skew_deg(num) let translateY: number = Math.tan(skew_deg * 2 * Math.PI / 360) * 100 let transform = `skew(0deg, -${skew_deg}deg) translateY(-${translateY}px)` return { transform, backgroundColor: getColor(), } } export default function () { return ( <div className={styles.normal}> <div className={styles.turntable}> <div className={styles.content}> {gift.map((item, index) => <div className={styles.box} key={item.name} style={{ transform: 'rotate(' + ((360 / gift.length) * index) + 'deg)' }}> <div className={styles.item} style={getItemStyle(gift.length)}> {item.name} <div className={styles.info} style={{ transform: `skew(0deg, ${get_skew_deg(gift.length)}deg) rotate(${(-(360 / gift.length) * index)}deg)` }}> <img style={{ display: 'block', width: 60, height: 60, borderRadius: '50%' }} src={yay} alt="" /> </div> </div> </div>) } </div> <div className={styles.arrow}></div> <div className={styles.point}></div> </div> </div> ); }