刚刚看到 Stack Overflow 的西班牙邀请函,参加新年最佳问答比赛,标签为算法。而且由于情人节快到了,我想收集算法来用 CSS、画布、SVG 或任何你认为的方式绘制心形。
更新
@Trauma 评论:
好吧,比赛很好,奖品就是奖品之类的,但是……这本身不应该是一个好问题吗?因为它是......它还有很多不足之处
这条评论让我觉得我必须在我的问题中添加一些代码,所以我开始了:
我用来画心的算法非常通用,因为我可以在 CSS、画布和 SVG 中使用它:
首先,我正在创建一个点数组
function corazon(r, paso) {
let puntos = [];
for (var a = 0; a < 2 * Math.PI; a += paso) {
let p = {};
p.x = cx + 16 * r * (Math.sin(a) * Math.sin(a) * Math.sin(a));
p.y =
cy -
13 * r * Math.cos(a) +
5 * r * Math.cos(2 * a) +
2 * r * Math.cos(3 * a) +
1 * r * Math.cos(4 * a);
puntos.push(p);
}
return puntos;
}
我在这里找到了这个公式在 C# 中绘制参数心形曲线
函数函数corazon()
返回一个点数组,我将使用这些点使用 HTML5 画布、SVG 以及最后的 CSS 和属性绘制一颗心box-shadow
在画布上
// inicia el canvas
const c = document.getElementById("canv");
const ctx = c.getContext("2d");
const cw = (c.width = 200);
const ch = (c.height = 200);
const cx = cw / 2,
cy = ch / 2;
// define el grosor de línea
ctx.lineWidth = 4;
// define el color de línea
ctx.strokeStyle = "crimson";
// el algoritmo del corazón
function corazon(r, paso) {
let puntos = [];
for (var a = 0; a < 2 * Math.PI; a += paso) {
let p = {};
p.x = cx + 16 * r * (Math.sin(a) * Math.sin(a) * Math.sin(a));
p.y =
cy -
13 * r * Math.cos(a) +
5 * r * Math.cos(2 * a) +
2 * r * Math.cos(3 * a) +
1 * r * Math.cos(4 * a);
puntos.push(p);
}
return puntos;
}
function dibujarCorazonEnCanvas() {
// crea un array vacío para guardar los puntos
let puntos = corazon(5, 0.05);
// empieza el trazado
ctx.beginPath();
// mueve el puntero al primer punto del array
ctx.moveTo(puntos[0].x, puntos[0].y);
// dibuja el corazon
puntos.forEach(p => {
ctx.lineTo(p.x, p.y);
});
// cierra el trazado
ctx.closePath();
// dibuja el corazón
ctx.stroke();
}
dibujarCorazonEnCanvas();
canvas{
border: 1px solid #d9d9d9;
}
<canvas id='canv'></canvas>
在 SVG 中
// el centro del lienzo SVG
const cx = 100,cy = 100;
function corazon(r, paso) {
let puntos = [];
for (var a = 0; a < 2 * Math.PI; a += paso) {
let p = {};
p.x = cx + 16 * r * (Math.sin(a) * Math.sin(a) * Math.sin(a));
p.y =
cy -
13 * r * Math.cos(a) +
5 * r * Math.cos(2 * a) +
2 * r * Math.cos(3 * a) +
1 * r * Math.cos(4 * a);
puntos.push(p);
}
return puntos;
}
function dibujarCorazonEnSVG() {
// crea el array de los puntos
let puntos = corazon(5, 0.05);
// crea una cadena de texto para el atributo d de un trazado path
let d = `M${puntos[0].x},${puntos[0].y}L`;
puntos.forEach(p => {
d += `${p.x},${p.y} `;
});
// establece el valor del atributo d
corazonSVG.setAttributeNS(null, "d", d);
}
dibujarCorazonEnSVG();
svg{
border: 1px solid #d9d9d9;
}
path {
fill: none;
stroke: crimson;
stroke-width: 4px;
}
<svg id="svg" viewBox = "0 0 200 200" width="200">
<path id="corazonSVG" d="" />
</svg>
在 CSS 中
我将使用相同的算法来绘制一颗心box-shadow
。我将使用 JavaScript 来计算box-shadow
.
// crea una nueva hoja de estilos y la agrega al head
const s = document.createElement("style");
document.head.appendChild(s);
// el centro del div
const cx = 100,cy = 100;
// el algoritmo del corazón
function corazon(r, paso) {
let puntos = [];
for (var a = 0; a < 2 * Math.PI; a += paso) {
let p = {};
p.x = cx + 16 * r * (Math.sin(a) * Math.sin(a) * Math.sin(a));
p.y =
cy -
13 * r * Math.cos(a) +
5 * r * Math.cos(2 * a) +
2 * r * Math.cos(3 * a) +
1 * r * Math.cos(4 * a);
puntos.push(p);
}
return puntos;
}
function dibujarCorazonBoxShadow() {
// crea el array de los puntos
let puntos = corazon(5, 0.01);
// un array par los fragmentos de reglas css para box-shadow
let reglas = [];
// para cada punto en el array
puntos.forEach(p => {
reglas.push(`${p.x}px ${p.y}px 0px 1px crimson`);
});
// construye el valor de box-shadow utilizando la propiedad textContent de la nueva hoja de estilo
s.textContent = "div::before{box-shadow:";
s.textContent += reglas.join();
s.textContent += ";}";
}
dibujarCorazonBoxShadow();
div {
border: 1px solid #d9d9d9;
width: 200px;
height: 200px;
position: relative;
}
div::before {
content: "";
width: 1px;
height: 1px;
border-radius: 50%;
position: absolute;
top: 0px;
left: 0px;
}
<div></div>
如何画一颗心用原语解释,问候
En R hay varias formas que se pueden ver aquí, la que mas me convence es la que usa una ecuación parámetrica en particular para construir un "cardioide":
Explicación:
t <- seq(0, 2*pi, by=0.1)
generamos una secuencia de números que van de0
a 2 vecespi
en pasos de 0.1x
ey
generamos estos valores que representarán los puntos externos de la formaplot(x, y, type="l")
vamos dibujando líneas a partir de cada pareja de puntosx
,y
. Conpolygon(x, y, col="hotpink")
creamos un polígono con la forma dada por los puntos y lo rellenamos con color.Otra opción es el path con Bezier Curve de Ricardo Cabello en uno de sus demos de como crear shapes con THREE.js.
Aquí un demo que hice usando esa figura agregándole algo de extrude para darle volúmen y multiplicándola:
Dejo mi aporte de un corazón con brillo en SVG jeje
no es un algoritmo como tal, solo una forma de dibujar un corazón con gradient.
https://codepen.io/memoadian/pen/vvMZOK
亲爱的老 Codepen
https://codepen.io/stellina91/pen/grIHf
https://codepen.io/kunalvarma05/pen/mJbBNY
https://codepen.io/mindstorm/pen/aZZvKq
https://codepen.io/tameraydin/pen/bAfws
https://codepen.io/vivinantony/pen/gbENBB
示例来源:
Agrego el código logo. Lo generé automáticamente usando una librería mía que convierte un path svg a comandos logo.
Esta es la imagen svg que utilicé, tal cual como la bajé de flaticon:
Esta es la misma imagen en png
Este es el código en python que utilizo para convertir el path svg a logo. Genero dos scripts, el primero es para MSWLogo y el segundo para otros intérpretes
Este es el script generado para MSWLogo
Este es el código generado para otros intérpretes
En la primera parte de los scripts se incluyen funciones generales y al final se incluyen los comandos que realizan el dibujo en sí
Este es el resultado de ejecutar el segundo script en https://www.calormen.com/jslogo/
Acá explico como funciona la biblioteca http://lopezezequiel.com/svgpath2logo/
Acá esta el repo https://github.com/lopezezequiel/SvgPath2Logo
Corazon en HTML CSS
corazon que late en mouse hover !
A la clase
Corazon
se le da una medida teniendo en cuenta el siguiente dato :el margen es a eleccion, en este caso lo use mas que nada para centrarlo.
a este punto creamos 2 rectangulos, aprovechando el
:before
y el:after
, a estos les agregamos el radius a los angulos superiores, que tienen que tener un radius que tiene que ser la mitad del width (no funciona con el 50%).el width de los rectangulos es la mitad del
width
de la clase corazon. mientras alheight
se le saca, mas o menos un 5% de la altura de la clase.despues se rotean gracias al
transform: rotate()
nuestrosbefore
yafter
uno de45deg
y el otro de-45deg
. recordar que elafter
, que en este caso esta girado de-45deg
, tiene que tener la propriedadleft
con un valor equivalente a su width.Le agregamos tambien el
box-shadow
para hacer mas atractiva nuestra figura, aca es a gusto proprio.y le agregamos una animacion en
hover
que aumente su medida, en los porcentajes :0% 20% 40% y 100%
.espero que les guste !!
Una forma de dibujar un corazón via css:
1. 用于 SVG 和 Canvas 的算法
Este es un algoritmo que utiliza Ana Tudor en algunos pens. He adaptado este algoritmo para utilizarlo en SVG y en canvas:
2. Otra manera de dibujar un corazón en CSS
En este caso utilizo dos elementos
div
con bordes redondeados. Esto crea dos óvalos que estoy girando hacia la derecha y hacia la izquierda. Puede cambiar el valor de la variable--h
para generar corazones de varios tamaños.