diff --git a/index.html b/index.html index a988406..f68236f 100755 --- a/index.html +++ b/index.html @@ -24,207 +24,53 @@ const detailScreens = []; detailScreens.push({ title: "Sección del Kit", - description: `
Párrafo uno -
-Párrafo dos
-Párrafo tres
-- Ejemplo de link o descarga -
`, - sourceCodes: [{ - title: "l", - content: `l` - }] - }); - detailScreens.push({ - title: "Tree", - description: `We can’t always use basic shapes to assemble our image. A polygon is the simplest way to draw a freeform shape. Here we set a list of coordinates that are connected with straight lines.
`, - sourceCodes: [{ - type: "HTML", - content: `` - }] - }); - detailScreens.push({ - title: "Gingerbread figure", description: `Since our SVG is living inside an HTML file now, we can assign CSS classes to each tag and move some attributes to CSS. You can only move the presentation attributes though. Position attributes and attributes that define the shape still have to stay in HTML. But colors, stroke, and font attributes can be moved to CSS.
We already saw the fill and some of the stroke properties, but here’s another one. The stroke-linecap. This can make our line cap round. Note that the legs and the arms are simple lines here. To give you a comparison if we remove the line cap and set a smaller stroke-width, then this is how it would looks like. But by setting a thick stroke width and a round line cap we can shape legs and arms for our figure.
Also, note the rx property at the rectangle defining the mouth. This will make the edges round. You can think of it as border-radius if you like.
`, - sourceCodes: [{ - type: "HTML", - content: `` - }, - { - type: "CSS", - content: `.gingerbread .body { - fill: #cd803d; -} +Also, note the rx property at the rectangle defining the mouth. This will make the edges round. You can think of it as border-radius if you like.
`, + }); -.gingerbread .eye { - fill: white; -} + detailScreens.push({ + title: "Gingerbread figure", + description: `Since our SVG is living inside an HTML file now, we can assign CSS classes to each tag and move some attributes to CSS. You can only move the presentation attributes though. Position attributes and attributes that define the shape still have to stay in HTML. But colors, stroke, and font attributes can be moved to CSS.
-.gingerbread .mouth { - fill: none; - stroke: white; - stroke-width: 2px; -} +We already saw the fill and some of the stroke properties, but here’s another one. The stroke-linecap. This can make our line cap round. Note that the legs and the arms are simple lines here. To give you a comparison if we remove the line cap and set a smaller stroke-width, then this is how it would looks like. But by setting a thick stroke width and a round line cap we can shape legs and arms for our figure.
-.gingerbread .limb { - stroke: #cd803d; - stroke-width: 35px; - stroke-linecap: round; -}` - } - ] +Also, note the rx property at the rectangle defining the mouth. This will make the edges round. You can think of it as border-radius if you like.
`, }); + detailScreens.push({ title: "House", - sourceCodes: [{ - type: "HTML", - content: `` - }, - { - type: "CSS", - content: `.house { - stroke: black; - stroke-width: 2px; - fill: white; -} - -.house .roof { - fill: none; - stroke: #d1495b; - stroke-width: 10px; - stroke-linecap: round; -} - -.house .door { - fill: #d1495b; - rx: 2px; -} - -.house .stair { - fill: gray; -} + description: `Since our SVG is living inside an HTML file now, we can assign CSS classes to each tag and move some attributes to CSS. You can only move the presentation attributes though. Position attributes and attributes that define the shape still have to stay in HTML. But colors, stroke, and font attributes can be moved to CSS.
-.house .window { - fill: #fdea96; - rx: 5px; -} +We already saw the fill and some of the stroke properties, but here’s another one. The stroke-linecap. This can make our line cap round. Note that the legs and the arms are simple lines here. To give you a comparison if we remove the line cap and set a smaller stroke-width, then this is how it would looks like. But by setting a thick stroke width and a round line cap we can shape legs and arms for our figure.
-.house .window-sill { - fill: #d1495b; - stroke-linecap: round; - rx: 5px; -}` - } - ] +Also, note the rx property at the rectangle defining the mouth. This will make the edges round. You can think of it as border-radius if you like.
`, }); + detailScreens.push({ title: "Christmas bauble with clip-path", description: `This bauble has a motif on its side defined as a polyline. Polylines normally wouldn't care about the edge of the ball. Part of the line would overhang or stop too soon. We use clip-path here to make sure that the motif fits perfectly with the ball.
We define the motif to be bigger than the ball then we cut the overhanging parts with a clip-path. The clip-path is defined in the definitions section. The defs section is like a hidden compartment of our image. Things here don't show up as part of our image, but we can refer to them and use them later.
`, - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Star", description: `A star is a simple shape, so we could define it as a bunch of polygons and set each point individually. But then we would need to know each coordinate. Instead of that, we can just define one wing, then repeat it five times with a rotation to get the same shape. We use the transform attribute to set a rotation.
In this example, each wing consists of two polygons. They need to be rotated the same way, so we can group them with a g tag and rotate them together. You can think of the g tag as the div tag in HTML. On its own, it does not represent anything. But it can contain other elements and attributes defined on the group tag apply to its children.
`, - sourceCodes: [{ - type: "HTML", - content: `` - }] + }); detailScreens.push({ title: "Snowflake", @@ -233,813 +79,138 @@The branch is defined as a path. The path is the most powerful SVG tag. We can define pretty much anything with paths and if you open any SVG file, you will see paths mostly.
The shape of the path is defined by the d attribute. Here we define several drawing commands. A command always starts with a letter defining the command type and ends with a coordinate. Here we only have the two most simple commands, move to and line to. The move to command moves the cursor to a point without drawing a line and the line to command draws a straight line from the previous point. A command always continues the previous command so when we draw a line we only define the endpoint. The starting point will be the previous command’s endpoint. This path is a bit unusual because there are several move to commands in it to draw the main branch and each side branches with the same path.
`, - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Forest", - description: `Rotation is not the only way we can generate images from simple shapes. In this example, we define a tree shape then place it to various positions in different sizes to draw a forest.`, - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Christmas bauble with gradient", - description: `The filling of a shape can be defined as a gradient. Here we apply a radial gradient to our Christmas decoration to have a subtle 3D effect. It has a different syntax than CSS but the capabilities are rather similar. Gradients in SVG though can also be applied for strokes and pretty cool effects can be achieved that way.`, - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Snowman", - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Quadratic Bézier", - description: `The path element becomes really powerful when we start using curves. One of them is the quadratic Bezier curve that not only defines an endpoint for a segment but also has a control point. The control point is an invisible coordinate to which the line is bending to, but not touching it. Here we have a series of quadratic beziers where the control points get further and further away from the center of the tree as the path goes down.`, - sourceCodes: [{ - type: "HTML", - content: `` - }] + description: `Since our SVG is living inside an HTML file now, we can assign CSS classes to each tag and move some attributes to CSS. You can only move the presentation attributes though. Position attributes and attributes that define the shape still have to stay in HTML. But colors, stroke, and font attributes can be moved to CSS.
+ +We already saw the fill and some of the stroke properties, but here’s another one. The stroke-linecap. This can make our line cap round. Note that the legs and the arms are simple lines here. To give you a comparison if we remove the line cap and set a smaller stroke-width, then this is how it would looks like. But by setting a thick stroke width and a round line cap we can shape legs and arms for our figure.
+ +Also, note the rx property at the rectangle defining the mouth. This will make the edges round. You can think of it as border-radius if you like.
`, + }); detailScreens.push({ title: "Cubic Bézier", description: `While the quadratic bezier is great when we want to bend a line, often it’s not flexible enough. With cubic Bezier, we not only one have one control point but two. The first control point sets the initial direction of the curve and the second one defines from which direction should the curve arrive to its endpoint. If these directions match the directions of the line before and the line after the curve, then we have a smooth transitioning between the path segments.
In this example the ribbon of the gift box uses a cubic Bezier that smoothly continues the previous straight line then turns back to the direction of the upcoming line.
`, - sourceCodes: [{ - type: "HTML", - content: `` - }, - { - type: "CSS", - content: `.gift .box { - fill: #d1495b; - stroke: black; - stroke-width: 2px; -} +We already saw the fill and some of the stroke properties, but here’s another one. The stroke-linecap. This can make our line cap round. Note that the legs and the arms are simple lines here. To give you a comparison if we remove the line cap and set a smaller stroke-width, then this is how it would looks like. But by setting a thick stroke width and a round line cap we can shape legs and arms for our figure.
-.gift .stripe { - fill: white; - stroke: black; - stroke-width: 2px; -} +Also, note the rx property at the rectangle defining the mouth. This will make the edges round. You can think of it as border-radius if you like.
`, -.gift .ribbon { - stroke: #b73a3b; - stroke-width: 4px; - fill: none; -}` - } - ] - }); - detailScreens.push({ - title: "Bell", - description: `Let’s have another example with cubic and quadratic beziers. Here the bottom of this bell is defined with straight lines. Then a quadratic Beziers starts the bell cloak. Then the line is continued with a cubic Bezier to form the top of the bell. Then we reach the bottom part with another quadratic bezier.`, - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Arc", description: `If you thought that cubic Beziers are the most complicated parts of SVGs then I have bad news for you. Arcs are even more complicated.
The last two parameters are still the endpoint of the arc. Arcs have five extra parameters on top of that though. You define a horizontal and vertical radius for an arc. If these two values are not the same then you end up with an ellipse. If you draw an ellipse you can also turn it by an angle, which will be the third parameter. Given the starting point coming from the previous segment, given the endpoint defined here, and the radiuses there are still two possible arc centers and four possible arcs to draw. The last two parameters of an arc are to pick one of these four options.
`, - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Ribbon", - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Bear", - sourceCodes: [{ - type: "HTML", - content: `` - }, - { - type: "CSS", - content: `.bear { - background-color: #f5eed7; -} +We already saw the fill and some of the stroke properties, but here’s another one. The stroke-linecap. This can make our line cap round. Note that the legs and the arms are simple lines here. To give you a comparison if we remove the line cap and set a smaller stroke-width, then this is how it would looks like. But by setting a thick stroke width and a round line cap we can shape legs and arms for our figure.
-.bear .face { - fill: white; - rx: 50; - ry: 30; -} +Also, note the rx property at the rectangle defining the mouth. This will make the edges round. You can think of it as border-radius if you like.
`, -.bear .mouth { - fill: none; - stroke: black; - stroke-width: 2; -}` - } - ] }); detailScreens.push({ title: "Text Path", description: `Drawing shapes are not the only use case for paths. We can also use them to render a text along an invisible path. We can define a path in the definitions section to make sure it's invisible. Then we refer to it in the textPath attribute to make a text go around a circle. Here we use arc again, but you can use any other path and the text will follow it.`, - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Path based animation", description: `Another fun use of paths is to create animation paths. This method is not SVG only. I’m using a CSS property here that works for any other HTML tag. But if you check the value of this attribute, you see that we define a path the same way as we do for SVGs.
To give you a fair warning though, this feature at this point is rather experimental at this point and it’s not supported for Safari. There’s also an old SVG specific way for doing the same thing with animationMotion. Unfortunately, that’s rather obsolete. So at this point, neither of these are fully supported, but I’m sure there’s going to be a way in the future to use paths for animation.
`, - sourceCodes: [{ - type: "HTML", - content: `` - }, - { - type: "CSS", - content: `.sleigh { - offset-path: path( - "M-200 80 L -90 80 Q 60 80 60 -10 A 50 50 0 0 0 -60 -10 Q -60 80 90 80 L 200 80" - ); - animation: roller-coaster 6000ms infinite linear; -} -@keyframes roller-coaster { - 0% { - offset-distance: 0%; - } - 100% { - offset-distance: 100%; - } -}` - } - ] }); detailScreens.push({ title: "Ringing on hover", description: `A more traditional animation that certainly works in every browser is a ringing effect. We animate the transform property with keyframes. We can even trigger this effect on hovering. There’s nothing SVG specific here. The same works with any HTML element, but it’s a cool example of how to combine SVGs with CSS.`, - sourceCodes: [{ - type: "HTML", - content: `` - }, - { - type: "CSS", - content: `.bell:hover { - transform-origin: center 30%; -} -.bell:hover, -.bell:hover .bell-tongue { - animation-duration: 0.5s; - animation-delay: -0.25s; - animation-iteration-count: infinite; - animation-direction: alternate; - animation-timing-function: ease-in-out; - animation-name: ring; -} - -@keyframes ring { - from { - transform: rotate(-20deg); - } - to { - transform: rotate(20deg); - } -}` - } - ] }); detailScreens.push({ title: "Snowing", descritpion: `To continue our forest example we can add a snowing effect with a similar animation. We animate transform again, but this time we move many more elements. It's a bit glitchy and not the most sophisticated animation, but you get the idea.`, - sourceCodes: [{ - type: "HTML", - content: `` - }, - { - type: "CSS", - content: `.flake { - animation-duration: inherit; - animation-name: snowing; - animation-iteration-count: infinite; - animation-timing-function: linear; -} - -@keyframes snowing { - from { - transform: translate(0, -100px); - } - to { - transform: translate(0, 100px); - } -} - -.flake.opaque { - opacity: 0.7; -} - -.flake.slow { - animation-duration: 5s; -} - -.flake.fast { - animation-duration: 3s; -}` - } - ] }); detailScreens.push({ title: "Background pattern", description: `This example is a bit of an easter egg. For any HTML element, you can set a background image in CSS. Here we usually provide a link to an image, but we can also inline one here. Normally you wouldn't do that, because you end up with something gibberish in your CSS. If we do that with an SVG though then it’s not even that cryptic. This SVG code is still character encoded, so that’s why you still see some weird parts. The pointy brackets are replaced here. This is a great way to create background patterns with only a few lines of code in CSS. If you like this idea check out svgbackgrounds.com for a lot of great patterns.`, - sourceCodes: [{ - type: "HTML", - content: `` - }, - { - type: "CSS", - content: `.background { - background-color: #38755b; - background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='50' height='50' viewBox='0 0 120 120'%3E%3Cpolygon fill='%230c5c4c' points='120 120 60 120 90 90 120 60 120 0 120 0 60 60 0 0 0 60 30 90 60 120 120 120 '/%3E%3C/svg%3E"); -} - ` - } - ] + }); detailScreens.push({ title: "Clock", description: `SVG elements can be manipulated from JavaScript the same way as any other HTML tag. In this example we are using a short code snipped to show the actual time on a clock. You can even have a script tag inside the SVG but of course, you can have it outside of an SVG as well and refer to the elements the same way.
There’s another trick here worth mentioning. The dots here showing each hour are actually part of a circle. In CSS we can set the border-style to be dashed, but CSS is not too flexible on this one. SVG though took this to the next level and we can fine-tune the length of each dash segment and the space in between. That’s what we use here to show the dots for each hour.
`, - sourceCodes: [{ - type: "HTML", - content: `` - }] }); detailScreens.push({ title: "Interaction", description: `We can not only manipulate SVGs from JavaScript but we can also assign event listeners to parts of SVGs. Here, by clicking the red button we switch on or off the lights. The possibilities are endless. You can even create a full-featured game with SVG and JavaScript.`, - sourceCodes: [{ - type: "HTML", - content: `` - }, - { - type: "CSS", - content: `.lights { - fill: none; - stroke: #5f4c6c; - stroke-width: 2; -} - -.lights #button { - cursor: pointer; -}` - } - ] }); detailScreens.push({ title: "Data-driven diagram", description: `SVGs also work well with frontend libraries. Here I’m using React to generate a data-driven diagram. Here I’m both generating a list of rectangles to create a column diagram based on some data and I also generate a series of coordinates for a polyline.
For simple use cases, you can code your own diagram like this. But if you need more complex diagrams then check out the D3 library. The D3 library uses SVG under to hood to create all sorts of diagrams.
`, - sourceCodes: [{ - type: "JavaScript", - content: `function Diagram() { - const dataPoints = [3, 4, 7, 5, 3, 6]; - const sineWave = Array.from({ length: 115 }) - .map((item, index) => \`\${index - 55},\${Math.sin(index / 20) * 20 + 10}\`) - .join(" "); - - return ( - - ); -}` - }] }); detailScreens.push({ title: "Multi-component snow globe", description: `If you really got into SVGs and you got one where the code got a bit out of hand then you can break it down into components. Here I’m using React again, but the same things apply for Vue.JS. Mind though that there’s only one SVG tag at the root of the component as there's still only one image. The child components have their content in group elements.`, - sourceCodes: [{ - type: "JavaScript", - content: `function SnowGlobe() { - return ( - - ); -} - -function Threes() { - return ( -