ChatGPT解决这个技术问题 Extra ChatGPT

How do I create a teardrop in HTML?

How do I create a shape like this to display on a webpage?

I don't want to use images since they would get blurry on scaling

https://i.stack.imgur.com/3dFQ5.png

I tried with CSS:

.tear { display: inline-block; transform: rotate(-30deg); border: 5px solid green; width: 50px; height: 100px; border-top-left-radius: 50%; border-bottom-left-radius: 50%; border-bottom-right-radius: 50%; }

That turned out really screwed.

And then I tried with SVG:

It did get the shape, but the bottom part wasn't curved.

Is there a way to create this shape so it can be used in an HTML page?

"I don't want to use images since they would get blurry on scaling", why are you scaling the image? They don't get blurry if you use [srcset] or the <picture> element. Better yet, just link to an svg image: <img src="tear.svg" alt="Teardrop"/>
@zzzzBov: Are you really recommending the picture element? No support for IE, no support for early versions of Chrome, no support for safari. Should i continue?
@zzzzBov. why are you scaling the image? Well, the image can appear blurry without the dev scaling it. All you need for that is a browser zooming in. In my case, I have a HighDPI screen and plenty of blurry images. So, yeah, if you can avoid images using SVG, go for it.
Unicode solves it all... U+1F4A7 💧
@Thomas I see a square :/ i.stack.imgur.com/8fXMf.png

C
Community

SVG approach:

You can achieve the double curve easily with an inline SVG and the <path/> element instead of the <polygon/> element which doesn't allow curved shapes.

The following example uses the <path/> element with:

2 quadratic bezier curve commands for the 2 top curves (lines beginning with Q)

1 arc command for the big bottom one (line beginning with A)

SVG is a great tool to make this kind of shapes with double curves. You can check this post about double curves with an SVG/CSS comparison. Some of the advantages of using SVG in this case are:

Curve control

Fill control (opacity, color)

Stroke control (width, opacity, color)

Amount of code

Time to build and maintain the shape

Scalable

No HTTP request (if used inline like in the example)

Browser support for inline SVG goes back to Internet Explorer 9. See canIuse for more information.


it can reduce to: <svg width="100%" height="100%" viewBox="0 0 8 8" /> <path d="M4 1L3 4A1.2 2 0 1 0 5 4"/> </svg> ... this will fill the area you give it, so it may make "fat" or "skinny" raindrops ... change to fixed height/width if necessary
@technosaurus the problem with reducing the number of commands in the d="..." attribute is that you don't have the double curve at the top of the drop anymore.
+1 because you should use SVG for this, not CSS. The CSS features you'd need to achieve it have about the same browser support as SVG so there's no advantage for CSS on that score. CSS can do shapes, but that's not what it's designed for; don't try to hammer in a nail with a screwdriver just for the sake of being clever when you can do it just as well with a tool designed for the job.
Even better: create a SVG file and use <img /> in the hypertext document.
@AndreasRejbrand that can be a good idea depending on the project but it adds a HTTP request which OP seems to want to avoid.
j
jbutler483

Basic Border-Radius

You can do this within CSS relatively easily using border-radius' and transforms. Your CSS was just a little bit out.

.tear { width: 50px; height: 50px; border-radius: 0 50% 50% 50%; border: 3px solid black; transform: rotate(45deg); margin-top: 20px; }

Advanced Border-Radius

This will be very similar to above but gives it a bit more shape.

.tear { width: 50px; height: 50px; border-radius: 80% 0 55% 50% / 55% 0 80% 50%; border: 3px solid black; transform: rotate(-45deg); margin-top: 20px; }


@zzzzBov I don't fully understand how it is the wrong tool, OP asked for a CSS or SVG solution and i came up with a CSS solution which fits the description as close as possible. Its lightweight and easy to modify.
@zzzzBov Using CSS for images and sprites is common use. It is a very minimal piece of code to generate a generic "Image". I believe it is appropriate because it is usable within the questions spec of being usable on a web page.
@zzzzBov: CSS is perfectly fine for shapes. Who's to say what such shape is used for? semantically an image - OP has clearly stated they do not wish to use an image, otherwise why else would such a question be asked?
@jbutler483, "CSS is perfectly fine for shapes" no, it's awful. Just because you can doesn't mean you should. It introduces all sorts of garbage in markup, and is a tedious mess to maintain. Images are much simpler to maintain as they are easily separated into their own individual self-contained file.
'Garbage in the markup' occurs when you use bootstrap, or font awesome icons. Seriously, I think you're going a bit over the top for the likes of this when (quite obviously) this can be achieved using a border radius declaration. But hay, who's to tell you not to use images?
j
jbutler483

Your main issue with your CSS code was:

You used a different height than width You haven't rotated the correct angle size

So, by 'fixing' these issues, you would generate:

.tear { display: inline-block; transform: rotate(-45deg); border: 5px solid green; width: 100px; height: 100px; border-top-left-radius: 50%; border-bottom-left-radius: 50%; border-bottom-right-radius: 50%; } /***for demo only***/ .tear { margin: 50px; }

Please also note to save on CSS length, you could re-write your border-radius properties to:

border-radius: 50% 0 50% 50%;

this could be enhanced with pseudo elements as shown in this fiddle

Alternatives

I found this by Vinay Challuru on codepen.

Please note that with the logic here, I was able to create the SVG to nearly any possible build shape/etc. For example, a quick output was:

It's using an SVG and allows you to alter the shape in multiple ways, having the ability to alter its shape to the desired result:

var SVG = function() { this.element = document.getElementsByTagName("svg")[0]; this.namespace = "http://www.w3.org/2000/svg"; this.width = 400; this.height = 400; } /****Let's initialise our SVG ready to draw our shape****/ var svg = new SVG(); /****This sets up the user interface - we've included the script for this as an external library for the codepen****/ var gui = new dat.GUI(); /****Here's where the code to create the shape begins!****/ var Teardrop = function() { this.x = svg.width * 0.5; this.y = svg.height * 0.1; this.width = svg.width * 0.4; this.triangleHeight = svg.height * 0.5; this.yCP1 = svg.height * 0.2; this.yCP2 = svg.height * 0.45; this.element = null; this.ctrlPoints = []; this.anchors = []; this.fill = "none"; this.stroke = "#333"; this.strokeWidth = 2; this.showCtrlPoints = true; this.init(); } Teardrop.prototype.init = function() { this.element = document.createElementNS(svg.namespace, "path"); svg.element.appendChild(this.element); this.element.setAttribute("fill", this.fill); this.element.setAttribute("stroke", this.stroke); this.element.setAttribute("stroke-width", this.strokeWidth); for (var i = 0; i < 3; i++) { this.ctrlPoints.push(document.createElementNS(svg.namespace, "circle")); svg.element.appendChild(this.ctrlPoints[i]); this.ctrlPoints[i].setAttribute("fill", this.fill); this.ctrlPoints[i].setAttribute("stroke", 'red'); this.ctrlPoints[i].setAttribute("stroke-width", 1); this.anchors.push(document.createElementNS(svg.namespace, "line")); svg.element.appendChild(this.anchors[i]); this.anchors[i].setAttribute("stroke-width", 1); this.anchors[i].setAttribute("stroke", this.stroke); this.anchors[i].setAttribute("stroke-dasharray", "3,2"); } this.draw(); } Teardrop.prototype.draw = function() { this.radius = this.width / 2; path = [ "M", this.x, ",", this.y, "C", this.x, ",", this.yCP1, " ", this.x + this.width / 2, ",", this.yCP2, " ", this.x + this.width / 2, ",", this.y + this.triangleHeight, "A", this.radius, ",", this.radius, ",", "0 0,1,", this.x - this.width / 2, ",", this.y + this.triangleHeight, "C", this.x - this.width / 2, ",", this.yCP2, " ", this.x, ",", this.yCP1, " ", this.x, ",", this.y ]; this.element.setAttribute("d", path.join("")); cpCoords = []; cpCoords[0] = [this.x, this.yCP1]; cpCoords[1] = [this.x - this.width / 2, this.yCP2]; cpCoords[2] = [this.x + this.width / 2, this.yCP2]; anchorCoords = []; anchorCoords[0] = [this.x, this.y]; anchorCoords[1] = [this.x - this.width / 2, this.y + this.triangleHeight]; anchorCoords[2] = [this.x + this.width / 2, this.y + this.triangleHeight]; for (var i = 0; i < 3; i++) { this.ctrlPoints[i].setAttribute("cx", cpCoords[i][0]); this.ctrlPoints[i].setAttribute("cy", cpCoords[i][1]); this.anchors[i].setAttribute("x1", cpCoords[i][0]); this.anchors[i].setAttribute("x2", anchorCoords[i][0]); this.anchors[i].setAttribute("y1", cpCoords[i][1]); this.anchors[i].setAttribute("y2", anchorCoords[i][1]); if (this.showCtrlPoints) { this.ctrlPoints[i].setAttribute("r", 2); this.anchors[i].setAttribute("stroke-width", 1); } else { this.ctrlPoints[i].setAttribute("r", 0); this.anchors[i].setAttribute("stroke-width", 0); } } } var teardrop = new Teardrop(); gui.add(teardrop, 'triangleHeight', 0, svg.height * 0.75); gui.add(teardrop, 'width', 0, 200); gui.add(teardrop, 'yCP1', 0, svg.height); gui.add(teardrop, 'yCP2', 0, svg.height); gui.add(teardrop, 'showCtrlPoints', 0, svg.height); for (var i in gui.__controllers) { gui.__controllers[i].onChange(function() { teardrop.draw(); }); } html, body { height: 100%; } svg { display: block; margin: 0 auto; background: url('http://unitedshapes.com/images/graph-paper/graph-paper.png'); }

Disclaimer I did not write the above pen, only sourced it.

CSS Version

Although this is far from complete, you may also be able to generate this shape using CSS.

.tear{ height:200px; width:200px; background: linear-gradient(to bottom, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 29%,rgba(0,0,0,1) 30%,rgba(0,0,0,1) 100%); border-radius:50%; margin:120px; position:relative; } .tear:before{ content:""; position:absolute; top:-70%;left:0%; height:100%;width:50%; background: radial-gradient(ellipse at -50% -50%, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 75%,rgba(0,0,0,1) 76%,rgba(0,0,0,1) 100%); } .tear:after{ content:""; position:absolute; top:-70%;left:50%; height:100%;width:50%; background: radial-gradient(ellipse at 150% -50%, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 75%,rgba(0,0,0,1) 76%,rgba(0,0,0,1) 100%); }

SVG Version

I should know that SVG should be at the top of this answer, however, I like a challenge and so here is an attempt with SVG.

svg { height: 300px; } svg path { fill: tomato; }

Altering the path values, you would be able to alter the shape of your teardrop design.


These all seem very... verbose. The js solution is particularly absurd.
@egid: I did state in my answer that I did not create the js version. Also note the js version is allowing you to alter the shape at run time
M
Max Payne

IMO this shape requires smooth curve-to beziers to ensure continuity of the curve.

The Drop in question :

For the drop in question,

smooth curves can't be used, as control points wont be of same length. But we still need to make the control points lie exactly opposite (180 deg) to the previous control points, to ensure full continuity of curve The picture given below illustrates this point :

https://i.stack.imgur.com/37Xqa.png

stroke-linejoin="miter", for the pointed top part.

AS this shape only uses successive c commands, we can omit it.

Here's the final snippet:

TBH though, accepted answer's curves are not quite continuous.

For IE 5-8 (VML)

Only works in IE 5-8. VML uses different commands than SVG. Eg. it uses v for relative cubic beziers.

Note: This snippet won't run in IE 5-8 too. You need to create an html file and run it directly in the browser.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
    <style> v\:* { behavior: url(#default#VML); }

    </style >
</head>
<body>
    <div style="width:240; height:320;">
        <v:shape coordorigin="0 0" coordsize="12 16" fillcolor="white" strokecolor="black" strokewidth="1"
            strokeweight="5" style="width:240; height:320" 
            path="M 6 1 v -2 3 -5 5 -5 9
           0 7 10 7 10 0 
           0 -4 -3 -6 -5 -9 x e">
        </v:shape>
    </div>
</body>
</html>

"smooth curves can't be used, as control points wont be of same length." Doesn't "smooth" just mean that the tangent handles (control points) sit on a straight line? Why do they have to be of the same length?
@NiccoloM. In svg, smooth curve (T and S commands) means that the handle is symmetrically opposite, as well as equal to previous handle's length. In normal language, smooth curve might mean different handle lengths, but in svg, the length also is equal to previous curves handle :)
G
Gnubie

Or if your viewers' font supports it, use the Unicode characters

DROPLET: 💧 (💧)

or

BLACK DROPLET: 🌢 (🌢)

Scale accordingly!


You could use this with @font-face, but then you have a font file to keep in the right place and such.
SVG and a dedicated Unicode symbol like this is good. CSS for this is bad. PNG is okay, but not perfect since it is raster graphics. JPG is extremely bad, so bad that I would get nightmares if I saw it.
@AndreasRejbrand a 20x20 PNG would scale worst than a 200x200 JPG. And, with the same size, an uncompressed JPG is equivalent to a PNG. They are both raster and they suffer from the same issues.
@nico: In theory, yes, you can use JPG with zero compression. But the Internet is full of disasters like this one: en.wikipedia.org/wiki/Atomic_number#/media/…
D
Djave

I'd personally use an SVG for this. You can create SVGs in most vector graphics software. I'd recommend:

Inkscape

Sketch

Adobe Illustrator

I have made one below that is a tracing of your shape in Illustrator.


C
Community

HTML Canvas

This is an option uncovered in this thread so far. The commands used for Canvas drawings are very similar to SVG (and web-tiki deserves the credits for the base idea used in this answer).

The shape in question can be created either using canvas' own curve commands (Quadratic or Bezier) or the Path API. The answer contains examples for all three methods.

The browser support for Canvas is quite good.

Using Quadratic Curves

window.onload = function() { var canvas = document.getElementById('canvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.lineJoin = 'miter'; ctx.moveTo(120, 20); ctx.quadraticCurveTo(117.5, 30, 148, 68); ctx.arc(120, 88, 34.5, 5.75, 3.66, false); ctx.quadraticCurveTo(117.5, 35, 120, 20); ctx.closePath(); ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillStyle = '#77CCEE' ctx.stroke(); ctx.fill(); } } canvas { margin: 50px; height: 100px; width: 200px; transform: scale(1.5); } body{ background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%); }

Below is an advanced version with gradient fill and shadows. I have also included a hover effect on the shape to illustrate one drawback of Canvas when compared to SVG. Canvas is raster (pixel) based and hence would look blurred/pixelated when scaled beyond a certain point. The only solution to that would be to repaint the shape on every browser resize which is an overhead.

window.onload = function() { var canvas = document.getElementById('canvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); var lineargradient = ctx.createRadialGradient(135, 95, 1, 135, 95, 10); lineargradient.addColorStop(0, 'white'); lineargradient.addColorStop(1, '#77CCEE'); ctx.beginPath(); ctx.lineJoin = 'miter'; ctx.moveTo(120, 20); ctx.quadraticCurveTo(117.5, 30, 148, 68); ctx.arc(120, 88, 34.5, 5.75, 3.66, false); ctx.quadraticCurveTo(117.5, 35, 120, 20); ctx.closePath(); ctx.strokeStyle = '#333'; ctx.lineWidth = 3; ctx.fillStyle = lineargradient; ctx.shadowOffsetX = 2; ctx.shadowOffsetY = 2; ctx.shadowBlur = 2; ctx.shadowColor = "rgba(50, 50, 50, 0.5)"; ctx.stroke(); ctx.fill(); } } canvas { margin: 50px; height: 100px; width: 200px; transform: scale(1.5); } /* Just for demo */ body{ background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%); } canvas{ transition: all 1s; } canvas:hover{ transform: scale(2); }

Using Bezier Curves

window.onload = function() { var canvas = document.getElementById('canvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); var lineargradient = ctx.createRadialGradient(135, 95, 1, 135, 95, 10); lineargradient.addColorStop(0, 'white'); lineargradient.addColorStop(1, '#77CCEE'); ctx.beginPath(); ctx.lineJoin = 'miter'; ctx.arc(120, 88, 35, 5.74, 3.66, false); ctx.bezierCurveTo(100, 55, 122, 27.5, 120, 20); ctx.bezierCurveTo(122, 27.5, 121, 31.5, 150, 70); ctx.closePath(); ctx.strokeStyle = 'rgba(109,195,250,0.2)'; ctx.lineWidth = 1; ctx.fillStyle = lineargradient; ctx.shadowOffsetX = 2; ctx.shadowOffsetY = 2; ctx.shadowBlur = 2; ctx.shadowColor = "rgba(50, 50, 50, 0.5)"; ctx.stroke(); ctx.fill(); } } canvas { margin: 75px; height: 300px; width: 300px; transform: scale(1.5); } body { background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%); }

Using Path API

window.onload = function() { var canvas = document.getElementById('canvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.lineJoin = 'miter'; var p = new Path2D("M120 20 Q117.5 30 146 68 A34 34 0 1 1 92 68 Q117.5 35 120 20z"); ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillStyle = '#77CCEE' ctx.stroke(p); ctx.fill(p); } } canvas { margin: 50px; height: 100px; width: 200px; transform: scale(1.5); } body { background-image: radial-gradient(circle, #3F9CBA 0%, #153346 100%); }

Note: As mentioned in my answere here, the Path API is not yet supported by IE and Safari.

Further reading:

7 Reasons to Consider SVGs Instead of Canvas

HTML5 Canvas vs. SVG: Choose the Best Tool for the Job

What is the difference between SVG and HTML5 Canvas?


I dont see how svg is better option always. it certainly is better option in many cases like this one. But canvas has its own pros. Nice answer. from your answer i can make out that, it certainly is a lot easier to use SVG!
Yeah @TimKrul, its easier to write/use SVG. Canvas has its own pros but from whatever I read it is not too advantageous when using for simple logo like shapes primarily because it is raster based unlike SVG.
p
programking

I also found this on Codepen made by user Ana Tudor using CSS and the box-shadow style and parametric equations. Very simple, very little code. And many browsers support the CSS3 Box-shadow style:

body { background-color: black; } .tear { position: absolute; top: 50%; left: 50%; margin: -0.125em; width: 0.25em; height: 0.25em; border-radius: 50%; box-shadow: 0em -5em red, 0.00118em -4.97592em #ff1800, 0.00937em -4.90393em #ff3000, 0.03125em -4.7847em #ff4800, 0.07283em -4.6194em #ff6000, 0.13915em -4.40961em #ff7800, 0.23408em -4.15735em #ff8f00, 0.36em -3.86505em #ffa700, 0.51777em -3.53553em #ffbf00, 0.70654em -3.17197em gold, 0.92382em -2.77785em #ffef00, 1.16547em -2.35698em #f7ff00, 1.42582em -1.91342em #dfff00, 1.69789em -1.45142em #c7ff00, 1.97361em -0.97545em #afff00, 2.2441em -0.49009em #97ff00, 2.5em 0.0em #80ff00, 2.73182em 0.49009em #68ff00, 2.93032em 0.97545em #50ff00, 3.08681em 1.45142em #38ff00, 3.19358em 1.91342em #20ff00, 3.24414em 2.35698em #08ff00, 3.23352em 2.77785em #00ff10, 3.15851em 3.17197em #00ff28, 3.01777em 3.53553em #00ff40, 2.81196em 3.86505em #00ff58, 2.54377em 4.15735em #00ff70, 2.21783em 4.40961em #00ff87, 1.84059em 4.6194em #00ff9f, 1.42017em 4.7847em #00ffb7, 0.96608em 4.90393em #00ffcf, 0.48891em 4.97592em #00ffe7, 0.0em 5em cyan, -0.48891em 4.97592em #00e7ff, -0.96608em 4.90393em #00cfff, -1.42017em 4.7847em #00b7ff, -1.84059em 4.6194em #009fff, -2.21783em 4.40961em #0087ff, -2.54377em 4.15735em #0070ff, -2.81196em 3.86505em #0058ff, -3.01777em 3.53553em #0040ff, -3.15851em 3.17197em #0028ff, -3.23352em 2.77785em #0010ff, -3.24414em 2.35698em #0800ff, -3.19358em 1.91342em #2000ff, -3.08681em 1.45142em #3800ff, -2.93032em 0.97545em #5000ff, -2.73182em 0.49009em #6800ff, -2.5em 0.0em #7f00ff, -2.2441em -0.49009em #9700ff, -1.97361em -0.97545em #af00ff, -1.69789em -1.45142em #c700ff, -1.42582em -1.91342em #df00ff, -1.16547em -2.35698em #f700ff, -0.92382em -2.77785em #ff00ef, -0.70654em -3.17197em #ff00d7, -0.51777em -3.53553em #ff00bf, -0.36em -3.86505em #ff00a7, -0.23408em -4.15735em #ff008f, -0.13915em -4.40961em #ff0078, -0.07283em -4.6194em #ff0060, -0.03125em -4.7847em #ff0048, -0.00937em -4.90393em #ff0030, -0.00118em -4.97592em #ff0018; }


This doesn't resemble the kind of teardrop being asked for, though.
R
Ruddy

CSS Version

As there are a fair few answers here I thought why not add to it with another method. This is using both HTML and CSS to create the teardrop.

This will allow you to change the colour of the border and background of the teardrop and also re-size the top part of it.

Using a single div we can create a circle with border and border-radius. Then using pseudo elements (:before & :after) we create a CSS triangle more here, this will act as the tip of the teardrop. Using the :before as the border we place :after on top with a smaller size and the desired background colour.

div { width: 100px; height: 100px; border-radius: 50%; border: 4px solid; margin: 80px auto; position: relative; } div:before, div:after { content: ""; display: block; position: absolute; width: 0; height: 0; } div:before { border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 104px solid black; top: -75px; } div:after { border-left: 46px solid transparent; border-right: 46px solid transparent; border-bottom: 96px solid #fff; top: -66px; left: 0; right: 0; margin: auto; z-index: 1; }

Here is a demo of the teardrop with a background colour

div { width: 100px; height: 100px; border-radius: 50%; border: 4px solid; background: red; margin: 80px; position: relative; } div:before, div:after { content: ""; display: block; position: absolute; width: 0; height: 0; } div:before { border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid black; top: -70px; } div:after { border-left: 46px solid transparent; border-right: 46px solid transparent; border-bottom: 96px solid red; top: -66px; left: 0; right: 0; margin: auto; z-index: 1; }

It is as simple as putting a background colour onto the div and changing :after bottom-border colour to the same. To change the border you will need to change div border colour and :before background colour too.


Ruddy the pen is missing a background color value.
@Persijn Harry said something in chat and I was looking at it on that pen forgetting it auto saves every now and then. Haha, I will put it back the way it was. Done.
A
Anonymous

It is quite easy to do this with SVG by just using an image conversion resource such as http://image.online-convert.com/convert-to-svg, which was used to create the following:

Created by potrace 1.12, written by Peter Selinger 2001-2015


@Persijn why do you keep asking copied from some editor? Svg is svg , you can use whichever tool you want to create one.
@AbhinavGauniyal: 'editors' as you like to call them, add extra 'fluff' to declarations. For example, 300.000000pt and metadata that's not really needed
@Persijn what do you mean by hand/coded. Someone just made/hand/coded illustrator to just ease their coding tasks, and it still produces the same thing. Then again when you're using svg in browser, why don't you yourself hand/code it using assembly language? and why stop at assembly , hand/code it using wires or just draw it yourself. This is not a reason that I was expecting.
@jbutler483 yes and they can be trimmed out. There are many tools that do that for you , here's one for you github.com/svg/svgo
@persijn this answer provides the svg paths needed. i really have no clue what your objection is.
A
Andrew Willems

Here are four progressively simpler SVG teardrop shapes:

https://i.stack.imgur.com/A63rB.png

# of unique points: 8 7 4 3