用 clip-path: polygon() 绘制桃心形
<style>#mydiv {
width: 300px;
height: 300px;
background: purple;
transform: rotate(-180deg);
}
#msgBox { display: none; }
</style>
<div id="mydiv"></div>
<p>
<label for="angle">边缘系数 : </label>
<input id="angle" type="range" value="50" />
<span id="points">50</span>
<input id="loukong" type="checkbox" />
<label for="loukong">镂空</label>
<br><br>
<button id="showCode" value="1">查看代码</button>
<br><br>
</p>
<div id="msgBox"></div>
<script>
let toPercent = (num1,num2) => (num2 / num1 * 100).toFixed(2) + '%'; /* 转百分比 */
let mkHeart = (ww = 200, angle = 50, hollow = false) => {
let a = ww / 2, arr = hollow ? [`0% 0%, 100% 0%, 100% 100%, 50% 100%`] : [];
for(let i = 0; i <= 2 * Math.PI; i += Math.PI/angle) {
let x = a/17 * 16 * Math.pow(Math.sin(i), 3) + a;
let y = a/17 * (13 * Math.cos(i) - 5 * Math.cos(2 * i) - 2 * Math.cos(3 * i) - Math.cos(4 * i)) + a + 13;
arr.push(toPercent(a * 2, x) + ' ' + toPercent(a * 2, y));
}
if(hollow) arr.push(`50% 100%, 0% 100%`);
return `polygon(${arr.join(', ')})`;
}
msgBox.innerText = mydiv.style.clipPath = mkHeart();
showCode.onclick = () => showCode.innerText === '查看代码' ? (msgBox.style.display = 'block', showCode.innerText = '收起代码') : (msgBox.style.display = 'none', showCode.innerText = '查看代码');
loukong.onclick = angle.onchange = () => {
msgBox.innerText = mydiv.style.clipPath = mkHeart(200,angle.value,loukong.checked);
points.innerText = angle.value;
}
</script>
核心JS代码:
let toPercent = (num1,num2) => (num2 / num1 * 100).toFixed(2) + '%'; /* 转百分比 */
let mkHeart = (ww = 200, angle = 50, hollow = false) => {
/* 桃心形坐标方程式:
x = 16 * sint ^ 3
y = 13 * cost - 5 * cos2t - cos4t
*/
let a = ww / 2, arr = hollow ? [`0% 0%, 100% 0%, 100% 100%, 50% 100%`] : [];
for(let i = 0; i <= 2 * Math.PI; i += Math.PI/angle) {
let x = a/17 * 16 * Math.pow(Math.sin(i), 3) + a;
let y = a/17 * (13 * Math.cos(i) - 5 * Math.cos(2 * i) - 2 * Math.cos(3 * i) - Math.cos(4 * i)) + a + 13;
arr.push(toPercent(a * 2, x) + ' ' + toPercent(a * 2, y));
}
if(hollow) arr.push(`50% 100%, 0% 100%`);
return `polygon(${arr.join(', ')})`;
}函数 mkHeart(参数1, 参数2, 参数3) 的各参数都有预定值:参数1 ww 为200,是待剪裁正方形的宽高尺寸,参数2 angle 是边缘系数,默认50,值越大边缘越平滑;参数3 hollow 是镂空与否,默认为不镂空。该函数调用方法:
方法一:mkHeart();
方法二:mkHeart(300, 90, true); // true 镂空,false 不镂空
因为使用了百分比,所生成的 clip-path 代码适用于任意尺寸的正方形元素:
<style>
.mybox {
width: 400px;
height: 400px;
background: red;
clip-path: polygon(50.00% 71.21%, 50.01% 71.44%, 50.09% 72.14%, 50.31% 73.27%, 50.72% 74.78%, 51.39% 76.60%, 52.35% 78.64%, 53.63% 80.81%, 55.26% 83.01%, 57.24% 85.13%, 59.56% 87.09%, 62.19% 88.77%, 65.10% 90.12%, 68.23% 91.05%, 71.53% 91.52%, 74.92% 91.49%, 78.33% 90.96%, 81.67% 89.92%, 84.86% 88.40%, 87.82% 86.43%, 90.48% 84.06%, 92.76% 81.35%, 94.60% 78.35%, 95.95% 75.12%, 96.78% 71.74%, 97.06% 68.26%, 96.78% 64.74%, 95.95% 61.21%, 94.60% 57.71%, 92.76% 54.28%, 90.48% 50.91%, 87.82% 47.64%, 84.86% 44.45%, 81.67% 41.34%, 78.33% 38.31%, 74.92% 35.36%, 71.53% 32.46%, 68.23% 29.64%, 65.10% 26.87%, 62.19% 24.18%, 59.56% 21.58%, 57.24% 19.09%, 55.26% 16.74%, 53.63% 14.54%, 52.35% 12.55%, 51.39% 10.79%, 50.72% 9.29%, 50.31% 8.09%, 50.09% 7.21%, 50.01% 6.68%, 50.00% 6.50%, 49.99% 6.68%, 49.91% 7.21%, 49.69% 8.09%, 49.28% 9.29%, 48.61% 10.79%, 47.65% 12.55%, 46.37% 14.54%, 44.74% 16.74%, 42.76% 19.09%, 40.44% 21.58%, 37.81% 24.18%, 34.90% 26.87%, 31.77% 29.64%, 28.47% 32.46%, 25.08% 35.36%, 21.67% 38.31%, 18.33% 41.34%, 15.14% 44.45%, 12.18% 47.64%, 9.52% 50.91%, 7.24% 54.28%, 5.40% 57.71%, 4.05% 61.21%, 3.22% 64.74%, 2.94% 68.26%, 3.22% 71.74%, 4.05% 75.12%, 5.40% 78.35%, 7.24% 81.35%, 9.52% 84.06%, 12.18% 86.43%, 15.14% 88.40%, 18.33% 89.92%, 21.67% 90.96%, 25.08% 91.49%, 28.47% 91.52%, 31.77% 91.05%, 34.90% 90.12%, 37.81% 88.77%, 40.44% 87.09%, 42.76% 85.13%, 44.74% 83.01%, 46.37% 80.81%, 47.65% 78.64%, 48.61% 76.60%, 49.28% 74.78%, 49.69% 73.27%, 49.91% 72.14%, 49.99% 71.44%, 50.00% 71.21%);
}
</style>
<div class="mybox"></div> 板凳楼,代码产生的效果是一个尖尖朝上的桃心形,可以在 CSS 代码中加入 transform: rotate(xxdeg) 语句改变朝向,例如:
transform: rotate( -180deg); 纯CSS制作的桃心形:
<style>
.mybox {
width: var(--ww);
height: var(--ww);
background: red;
position: relative;
transform: rotate(-135deg);
margin: calc(var(--ww) / 2);
--ww: 120px;
}
.mybox::before, .mybox::after {
position: absolute;
content: '';
width: 100%;
height: 100%;
background: inherit;
border-radius: 50%;
}
.mybox::before {
top: calc(var(--ww) / 2);
}
.mybox::after {
left: calc(var(--ww) / 2);
}
</style>
<div class="mybox"></div>
<p>五楼代码的效果:<br><br></p>
<style>
.mybox {
width: var(--ww);
height: var(--ww);
background: red;
position: relative;
transform: rotate(-135deg);
margin: calc(var(--ww) / 2);
--ww: 120px;
}
.mybox::before, .mybox::after {
position: absolute;
content: '';
width: 100%;
height: 100%;
background: inherit;
border-radius: 50%;
}
.mybox::before {
top: calc(var(--ww) / 2);
}
.mybox::after {
left: calc(var(--ww) / 2);
}
</style>
<div class="mybox"></div> 马黑黑 发表于 2023-6-23 08:03
五楼代码的效果:
.mybox {
先去回想了一下纯CSS制作的心形,差点忘了。终于想起来了,是用两个半圆扣在旋转过的方形上的{:4_173:} 还是用 clip-path: polygon() 绘制的桃心形更漂亮,而且可以选择是否镂空,这个太厉害了{:4_199:} 边缘系数可调,更加清楚地看到了边缘少的时候锯齿很明显。去试了一下,从小到大一点点看着它的变化,非常有趣。感觉到36以上就已经感觉比较光滑了呢{:4_173:}
而且是用百分比设定的,可以适应任何尺寸的正方形。这个真的太好了{:4_199:} 都是数学公式的运用呢。这么好的帖子又想置顶了,可惜置顶的不少了,算了{:4_173:} 红影 发表于 2023-6-23 09:39
都是数学公式的运用呢。这么好的帖子又想置顶了,可惜置顶的不少了,算了
不用置顶的,已经置顶的,非必要的也可以放下来了 红影 发表于 2023-6-23 09:18
边缘系数可调,更加清楚地看到了边缘少的时候锯齿很明显。去试了一下,从小到大一点点看着它的变化,非常有 ...
40的边缘系数吧,比较靠谱 红影 发表于 2023-6-23 09:10
先去回想了一下纯CSS制作的心形,差点忘了。终于想起来了,是用两个半圆扣在旋转过的方形上的
实际上是整体旋转。两个圆是伪元素做的,移动一下位置。 红影 发表于 2023-6-23 09:12
还是用 clip-path: polygon() 绘制的桃心形更漂亮,而且可以选择是否镂空,这个太厉害了
前面做的,如果需要,也都可以做镂空的 黑黑辛苦,又出新的教程{:4_178:} 小辣椒 发表于 2023-6-23 12:30
黑黑辛苦,又出新的教程
喝水
{:4_190:} 马黑黑 发表于 2023-6-23 07:15
因为使用了百分比,所生成的 clip-path 代码适用于任意尺寸的正方形元素:
试试这一楼的代码 南无月 发表于 2023-6-23 17:37
试试这一楼的代码
试的怎么样 醉美水芙蓉 发表于 2023-6-23 18:33
这个非常漂亮!谢谢老师分享教程!
喝茶
{:4_180:}