{"id":1175,"url":"https://github.com/onmyway133/Snowflake","last_synced_at":"2025-08-06T13:32:40.836Z","repository":{"id":56911102,"uuid":"72376296","full_name":"onmyway133/Snowflake","owner":"onmyway133","description":"❄️  SVG in Swift","archived":false,"fork":false,"pushed_at":"2023-11-29T09:32:57.000Z","size":1850,"stargazers_count":962,"open_issues_count":5,"forks_count":54,"subscribers_count":16,"default_branch":"master","last_synced_at":"2024-11-28T23:27:56.246Z","etag":null,"topics":["html","ios","rss","svg","swift","xml"],"latest_commit_sha":null,"homepage":"https://onmyway133.com","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/onmyway133.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"onmyway133","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2016-10-30T21:22:17.000Z","updated_at":"2024-11-13T06:29:58.000Z","dependencies_parsed_at":"2024-01-02T20:58:05.585Z","dependency_job_id":"b0a107bb-76ab-4dd5-ad6a-ac5c52f40e88","html_url":"https://github.com/onmyway133/Snowflake","commit_stats":{"total_commits":151,"total_committers":4,"mean_commits":37.75,"dds":"0.019867549668874163","last_synced_commit":"c23a247a05182608d2023ff24c41d6f0c5998a2a"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onmyway133%2FSnowflake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onmyway133%2FSnowflake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onmyway133%2FSnowflake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onmyway133%2FSnowflake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onmyway133","download_url":"https://codeload.github.com/onmyway133/Snowflake/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228779141,"owners_count":17971086,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","ios","rss","svg","swift","xml"],"created_at":"2024-01-05T20:15:40.545Z","updated_at":"2024-12-09T14:31:01.557Z","avatar_url":"https://github.com/onmyway133.png","language":"Swift","readme":"# Snowflake\n\n\u003ca href=\"https://www.buymeacoffee.com/onmyway133\"\u003e \n    \u003cimg alt=\"Buy Me A Coffee\" src=\"https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png\" style=\"height: auto !important; width: auto !important;\" /\u003e \n\u003c/a\u003e\n\nCheckout https://indiegoodies.com/\n\n[![Version](https://img.shields.io/cocoapods/v/Snowflake.svg?style=flat)](http://cocoadocs.org/docsets/Snowflake)\n[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![License](https://img.shields.io/cocoapods/l/Snowflake.svg?style=flat)](http://cocoadocs.org/docsets/Snowflake)\n[![Platform](https://img.shields.io/cocoapods/p/Snowflake.svg?style=flat)](http://cocoadocs.org/docsets/Snowflake)\n![Swift](https://img.shields.io/badge/%20in-swift%204.0-orange.svg)\n\n![](Screenshots/Banner.png)\n\n## Description\n\n- SVG in Swift\n- Use XML parser from [Reindeer](https://github.com/onmyway133/Reindeer)\n\n## Usage\n\n### Document\n\n- Create a `Document` with SVG `Data`\n\n```swift\nguard let path = Bundle.main.path(forResource: \"xmas\", ofType: \"svg\"),\n  let data = try? Data(contentsOf: URL(fileURLWithPath: path)),\n   let document = Snowflake.Document(data: data)\n else { return }\n\nlet view = document.svg.view(size: CGSize(width: 100, height: 100))\n```\n\n\u003cdiv align = \"center\"\u003e\n\u003cimg src=\"Screenshots/xmas.png\" width=\"425\" height=\"197\" /\u003e\n\u003cbr\u003e\n\u003c/div\u003e\n\n- The flow is `SVG element` -\u003e `Shape` -\u003e `UIBezierPath` -\u003e `CALayer`\n- Make `Shape` from attributes\n\n```swift\nlet attributes: [String: Any] = [\n  \"fill\": \"#358245\",\n  \"stroke\": \"black\",\n  \"stroke-miterlimit\": \"10\",\n  \"d\": \"M308.3,102.3c4.5,8.2,9,16.2,13.2,24.3c7.2,13.9,15.8,26.9,25.6,39c10.1,12.4,21.5,23.6,33.6,34.1c2.5,2.1,5.2,3.9,8.1,6c-5.1,3.5-11.2,3.8-17,4.2c-11.9,0.9-23.7,1.5-36.4,2.3c22.7,46.7,59.7,74.6,109.7,88.1c-4.2,3.8-7.7,7.4-11.7,10.4c-11.3,8.6-24.4,13.7-38,17.4c-10.1,2.8-20.3,5-31.3,7.7c3.2,5,5.8,10.2,9.5,14.7c6.9,8.5,14.1,16.9,21.7,24.7c12.5,12.9,27.3,23,43.2,31c17.5,8.8,35.5,16.7,53.8,25.2c-3.4,3.1-6.9,7.1-11.2,10.1c-17,12.1-36.1,19.4-56.4,23.8c-8.7,1.9-17.3,3.7-27.5,5.8c5,4.7,9,9.2,13.7,12.6c13.2,9.4,26.4,19,40.4,27.1c11.8,6.9,24.6,12.1,37.3,17.4c10.4,4.3,21.1,7.7,31.7,11.5c1.1,0.4,2.3,0.5,4.4,0.9c-2.1,2.6-3.5,5.3-5.7,7c-6.7,5.3-13.2,10.8-20.5,15.1c-14.8,8.7-30.5,15.6-47.5,19.2c-17.8,3.8-35.6,3.1-53.3-0.8c-18.1-3.9-35.4-10.3-52.6-16.8c-5.7-2.2-11.7-3.7-17.5-5.8c-2.8-1-3.9,0.1-4.2,2.7c-1.1,11.3,2.7,22.1,15.6,22.4c2,0.1,3.9,0.6,5.9,0.7c6,0.3,8.7,3.1,7.7,9.1c-2,12.5-4.4,25-6.6,37.6c-2.6,14.6-5.1,29.2-7.6,43.8c-0.3,2-1.1,2.9-3.3,2.9c-17.2-0.1-34.4,0-51.6-0.1c-2.2,0-4.4-0.5-7-0.7c-1.2-6.4-2.4-12.8-3.5-19.2c-3.5-20.7-7-41.3-10.5-62c-1.8-10.5-1-9.6,8.8-11.5c4.4-0.8,9.1-1.5,13.1-3.5c5.8-2.9,8.8-15.1,6.1-21.1c-1-2.3-2.4-1.9-4.1-1.3c-10.5,3.9-21.1,7.8-31.6,11.8c-20.4,7.7-41.2,12.9-63.3,13.6c-26.3,0.8-49.9-6.4-72.4-18.8c-11.1-6.2-21.7-13.3-32.3-20.6c47.5-18,93.7-37,131.4-73.8c-35.8-5.2-68-17.1-97.8-38.3c5.2-2.4,9.3-4.5,13.6-6.1c26.2-9.7,50.5-23,72.6-40c17.5-13.4,32.1-29.6,43.7-48.5c0.3-0.4,0.4-0.9,0.6-1.5c-13.9-4-27.8-7.4-41.3-12.1c-13.5-4.7-26.3-11-37.1-22.2c4.8-2.1,9.1-4.3,13.5-6c19.2-7.5,36.9-17.5,52.4-31.2c15.1-13.4,27.5-29.1,38.1-46.2c0.7-1.1,1.3-2.3,1.9-3.5c0.5-1.2,1-2.4,1.5-3.9c-17.9-2.9-36.2,1.7-54.4-4.8c18.9-13.7,34.9-28.9,47.3-47.3C285.1,140.7,296.2,121.7,308.3,102.3z\"\n]\n\nlet path = Path(attributes: attributes)\nlet layer = path.layer\n```\n\n\u003cdiv align = \"center\"\u003e\n\u003cimg src=\"Screenshots/tree.png\" height=\"200\" width=\"200\" /\u003e\n\u003cbr\u003e\n\u003c/div\u003e\n\n### Shapes\n\n- The `Shape` object maps to SVG elements\n\t- path: `Path`\n\t- circle: `Circle`\n\t- line: `Line`\n\t- polygon: `Polygon`\n\t- polyline: `Polyline`\n\t- rect: `Rectangle`\n\t- ellipse: `Ellipse`\n\t- text: `Text`\n\t- image: `Image`\n\n- `Path` handles list of commands through `Command` object\n\n### Style\n\n- The `Style` object encapsulates style information\n\n```swift\nlet attributes: [String: Any] = [\n  \"fill\": \"lime\",\n  \"stroke\": \"purple\",\n  \"stroke-width\": \"5\",\n  \"fill-rule\": \"evenodd\"\n]\n\nlet style = Style(attributes: attributes)\n```\n\n- Inner style\n\n```xml\n\u003cpolygon points=\"100,10 40,198 190,78 10,78 160,198\" fill=\"lime\" stroke=\"purple\" stroke-width=\"5\" fill-rule=\"evenodd\" /\u003e\n```\n\n- Style attribute\n\n```xml\n\u003cpolygon points=\"100,10 40,198 190,78 10,78 160,198\" style=\"fill:lime;stroke:purple;stroke-width:5;fill-rule:evenodd;\" /\u003e\n```\n\n\u003cdiv align = \"center\"\u003e\n\u003cimg src=\"Screenshots/style.png\" /\u003e\n\u003cbr\u003e\n\u003c/div\u003e\n\n### Animation\n\n- The cool thing about `CALayer` is that most of its properties are animatable\n\n```swift\n(svgView.layer.sublayers as? [CAShapeLayer])?.forEach { layer in\n  let stroke = CABasicAnimation(keyPath: \"strokeEnd\")\n  stroke.fromValue = 0\n  stroke.toValue = 1\n  stroke.duration = 3\n\n  layer.add(stroke, forKey: nil)\n}\n```\n\n\u003cdiv align = \"center\"\u003e\n\u003cimg src=\"Screenshots/animation.gif\" /\u003e\n\u003cbr\u003e\n\u003c/div\u003e\n\n### Scale\n\n- Scale layers to a given size\n\n```swift\nlet layers = document.svg.layers(size: CGSize(width: 200, height: 100))\n```\n\n- Scale view to a given size\n\n```swift\nlet view = document.svg.view(size: CGSize(width: 100, height: 100))\n```\n\n\u003cdiv align = \"center\"\u003e\n\u003cimg src=\"Screenshots/scale.png\" /\u003e\n\u003cbr\u003e\n\u003c/div\u003e\n\n### Text\n\n- TBD\n\n### Image\n\n- Support base64 [Data URI](https://en.wikipedia.org/wiki/Data_URI_scheme)\n\n```swift\nlet attributes: [String: Any] = [\n  \"x\": \"0\",\n  \"y\": \"y\",\n  \"width\": \"100\",\n  \"height\": \"100\",\n  \"href\": \"data:image/png;base64,...\"\n]\n\nlet image = Image(attributes: attributes)\n```\n\n### Pattern\n\n- TBD\n\n## Installation\n\n**Snowflake** is available through [CocoaPods](http://cocoapods.org). To install\nit, simply add the following line to your Podfile:\n\n```ruby\npod 'Snowflake', git: 'https://github.com/onmyway133/Snowflake'\n```\n\nor \n\n```ruby\npod 'FantasticSnowflake'\n```\n\n**Snowflake** is also available through [Carthage](https://github.com/Carthage/Carthage).\nTo install just write into your Cartfile:\n\n```ruby\ngithub \"onmyway133/Snowflake\"\n```\n\n**Snowflake** can also be installed manually. Just download and drop `Sources` folders in your project.\n\n## Author\n\nKhoa Pham, onmyway133@gmail.com\n\n## Contributing\n\nWe would love you to contribute to **Snowflake**, check the [CONTRIBUTING](https://github.com/onmyway133/Snowflake/blob/master/CONTRIBUTING.md) file for more info.\n\n## License\n\n**Snowflake** is available under the MIT license. See the [LICENSE](https://github.com/onmyway133/Snowflake/blob/master/LICENSE.md) file for more info.\n","funding_links":["https://github.com/sponsors/onmyway133","https://www.buymeacoffee.com/onmyway133"],"categories":["Graphics","Libs","UI","Swift","Images [🔝](#readme)"],"sub_categories":["Getting Started","Images","Other free courses","Linter"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonmyway133%2FSnowflake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonmyway133%2FSnowflake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonmyway133%2FSnowflake/lists"}