最近项目需求,需要绘制一个圆球,两个相同圆心的椭圆,用以对应视频区域上的范围,会应用到一点点有趣的css知识,给大家分享一下。
思路
1,建议以画椭圆的方式去画圆,不要相信狗 * 品的花言巧语,都是骗纸!。
2,画椭圆有两种思路,建议选择思路二(直接画)
思路一. 画一个圆,然后用3D旋转来让他变成椭圆;
会出现两个问题
1,3D旋转会导致边框变成 dash 一样的形式, 有锯齿! 这点和拿图片进行3D旋转一样
2,画出来的椭圆范围,难以控制其与目标区域对应。
思路二. 直接画椭圆 border-radius: 50%;,宽高比不是1:1 即可画出椭圆。
3,多个椭圆组合成球、双椭圆重叠区域等需求实现时,建议优先考虑直接上定位!
先画两个简单的椭圆
html
<div class="circle circle-ps"></div>
<div class="circle-in circle-in-ps"></div>
css
.circle{
width: 200px;
height: 200px;
border-radius: 50%;
border: 1px solid rgba(253,73,84, 1);
box-shadow: inset 0 0 40px 0 rgba(253,73,84, 0.5);
margin-bottom: 20px;
}
.circle-in{
width: 200px;
height: 50px;
border-radius: 50%;
border: 1px solid rgba(253,73,84, 1);
box-shadow: inset 0 0 40px 0 rgba(253,73,84, 0.5);
margin-bottom: 20px;
}
组合成球
css
.circle-ps, .circle-in-ps{
position: absolute;
left: 200px;
top: 200px;
transform: translate(-50%, -50%);
}
组成相同圆心的椭圆
<div class="circle-oval"></div>
<div class="circle-in-oval"></div>
.circle-oval{
width: 400px;
height: 100px;
border-radius: 50%;
border: 1px solid rgba(59,194,133,1);
box-shadow: inset 0 0 40px 0 rgba(59,194,133,.5);
margin-bottom: 20px;
}
.circle-in-oval{
width: 300px;
height: 50px;
border-radius: 50%;
border: 1px solid rgba(255,185,74,1);
box-shadow: inset 0 0 40px 0 rgba(255,185,74, .5);
margin-bottom: 20px;
}
.circle-oval, .circle-in-oval{
position: absolute;
left: 400px;
top: 400px;
transform: translate(-50%, -50%);
}
让我们用vue3封装一下
Circle/index.vue
<template>
<div
class="circle"
:style="{
width: longD + 'px',
height: (shotD || longD) + 'px',
border: `1px solid rgba(${rgbColor}, 1)`,
'box-shadow': `inset 0 0 100px 0 rgba(${rgbColor})`,
position: centerLongLat && centerLongLat.length === 2 ? 'absolute' : 'static',
left: centerLongLat && ( centerLongLat[0] + 'px' ),
top: centerLongLat && ( centerLongLat[1] + 'px' ),
transform: centerLongLat ? 'translate(-50%, -50%)': 'none'
}"
>
<slot></slot>
</div>
</template>
<script setup lang="ts">
defineProps<{
centerLongLat?: number[] | undefined, // 圆心位置
longD: number; // 长直径
shotD?: number; // 短直径。没传则默认和 width 一致
rgbColor: string; // 圆的颜色
}>()
</script>
<style scoped>
.circle{
border-radius: 50%;
outline:1px solid transparent;
}
</style>
使用示例
<Circle
class="circle"
v-if="sphere.longLat.length > 0 && sphere.longD && sphere.shotD"
:rgb-color="sphere.rgbColor"
:long-d="sphere.longD"
:shot-d="sphere.shotD"
:center-long-lat="sphere.longLat"
/>
const sphere = ref({
longLat: [],
longD: 0, // 内外圆公用长边
shotD: 0, // 外圆短边
rgbColor: '253,73,84, 1'
})
完结~