mirror of
https://github.com/exyte/Macaw.git
synced 2024-09-21 01:47:44 +03:00
Merge pull request #401 from f3dm76/task/effectsOrder
Change effects order
This commit is contained in:
commit
9fdf3c72ee
@ -15,9 +15,7 @@
|
||||
575129B61CBD14AF00BD3C2E /* AnimationsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 575129B51CBD14AF00BD3C2E /* AnimationsView.swift */; };
|
||||
57AF398C1E67E9DB00F0BFE2 /* EventsExampleController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57AF398B1E67E9DB00F0BFE2 /* EventsExampleController.swift */; };
|
||||
58E4D50C1D841C6E00EC8815 /* TransformExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58E4D50B1D841C6E00EC8815 /* TransformExampleView.swift */; };
|
||||
5B1AE0F920B58575007EECCB /* SVGExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B1AE0F720B58574007EECCB /* SVGExampleViewController.swift */; };
|
||||
5B1AE0FA20B58575007EECCB /* SVGViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B1AE0F820B58574007EECCB /* SVGViewController.swift */; };
|
||||
5B1AE0FC20B5859E007EECCB /* shadows.svg in Resources */ = {isa = PBXBuildFile; fileRef = 5B1AE0FB20B5859E007EECCB /* shadows.svg */; };
|
||||
5BAE3CB120C54E3D006BEF51 /* FiltersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BAE3CB020C54E3D006BEF51 /* FiltersViewController.swift */; };
|
||||
66AE19DB1CC8CB3C00B78B5E /* tiger.svg in Resources */ = {isa = PBXBuildFile; fileRef = 66AE19DA1CC8CB3C00B78B5E /* tiger.svg */; };
|
||||
B02E75F11C16104900D1971D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B02E75F01C16104900D1971D /* AppDelegate.swift */; };
|
||||
B02E75F61C16104900D1971D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B02E75F41C16104900D1971D /* Main.storyboard */; };
|
||||
@ -50,9 +48,7 @@
|
||||
575129B51CBD14AF00BD3C2E /* AnimationsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnimationsView.swift; sourceTree = "<group>"; };
|
||||
57AF398B1E67E9DB00F0BFE2 /* EventsExampleController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventsExampleController.swift; sourceTree = "<group>"; };
|
||||
58E4D50B1D841C6E00EC8815 /* TransformExampleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransformExampleView.swift; sourceTree = "<group>"; };
|
||||
5B1AE0F720B58574007EECCB /* SVGExampleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SVGExampleViewController.swift; sourceTree = "<group>"; };
|
||||
5B1AE0F820B58574007EECCB /* SVGViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SVGViewController.swift; sourceTree = "<group>"; };
|
||||
5B1AE0FB20B5859E007EECCB /* shadows.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = shadows.svg; path = Example/Assets/SVG/shadows.svg; sourceTree = "<group>"; };
|
||||
5BAE3CB020C54E3D006BEF51 /* FiltersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FiltersViewController.swift; sourceTree = "<group>"; };
|
||||
66AE19DA1CC8CB3C00B78B5E /* tiger.svg */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = tiger.svg; path = Example/Assets/SVG/tiger.svg; sourceTree = "<group>"; };
|
||||
B02E75ED1C16104900D1971D /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B02E75F01C16104900D1971D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
@ -97,7 +93,7 @@
|
||||
574EC4271CB7DE7F0063F317 /* Examples */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5B1AE0F620B58574007EECCB /* SVG */,
|
||||
5BAE3CAF20C54DA5006BEF51 /* Filters */,
|
||||
57AF398A1E67E86400F0BFE2 /* Events */,
|
||||
5747F9BB1E38B660004E338F /* Morphing */,
|
||||
6699B7CE1DFFE8B90072585E /* Transform */,
|
||||
@ -135,13 +131,12 @@
|
||||
path = Events;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
5B1AE0F620B58574007EECCB /* SVG */ = {
|
||||
5BAE3CAF20C54DA5006BEF51 /* Filters */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5B1AE0F720B58574007EECCB /* SVGExampleViewController.swift */,
|
||||
5B1AE0F820B58574007EECCB /* SVGViewController.swift */,
|
||||
5BAE3CB020C54E3D006BEF51 /* FiltersViewController.swift */,
|
||||
);
|
||||
path = SVG;
|
||||
path = Filters;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
65CBD13FE29C7F0265D0E051 /* Frameworks */ = {
|
||||
@ -171,7 +166,6 @@
|
||||
66AE19D91CC8CAB600B78B5E /* SVG */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5B1AE0FB20B5859E007EECCB /* shadows.svg */,
|
||||
66AE19DA1CC8CB3C00B78B5E /* tiger.svg */,
|
||||
);
|
||||
name = SVG;
|
||||
@ -273,7 +267,6 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5B1AE0FC20B5859E007EECCB /* shadows.svg in Resources */,
|
||||
B02E75FB1C16104900D1971D /* LaunchScreen.storyboard in Resources */,
|
||||
B02E75F81C16104900D1971D /* Assets.xcassets in Resources */,
|
||||
66AE19DB1CC8CB3C00B78B5E /* tiger.svg in Resources */,
|
||||
@ -349,10 +342,9 @@
|
||||
575129B61CBD14AF00BD3C2E /* AnimationsView.swift in Sources */,
|
||||
58E4D50C1D841C6E00EC8815 /* TransformExampleView.swift in Sources */,
|
||||
B02E75F11C16104900D1971D /* AppDelegate.swift in Sources */,
|
||||
5BAE3CB120C54E3D006BEF51 /* FiltersViewController.swift in Sources */,
|
||||
57AF398C1E67E9DB00F0BFE2 /* EventsExampleController.swift in Sources */,
|
||||
B04416FA1E041A420016BC50 /* EasingView.swift in Sources */,
|
||||
5B1AE0F920B58575007EECCB /* SVGExampleViewController.swift in Sources */,
|
||||
5B1AE0FA20B58575007EECCB /* SVGViewController.swift in Sources */,
|
||||
574EC4411CB7E2440063F317 /* MenuViewController.swift in Sources */,
|
||||
574EC43E1CB7DE7F0063F317 /* ShapesExampleView.swift in Sources */,
|
||||
B04416FC1E04282A0016BC50 /* EasingExampleController.swift in Sources */,
|
||||
|
@ -1,51 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
|
||||
<defs>
|
||||
<filter id="colorFilter" x="0" y="0" width="200%" height="200%">
|
||||
<feOffset result="offOut" in="SourceGraphic" dx="20" dy="20" />
|
||||
<feColorMatrix type="matrix" result="colorOut" in="offOut"
|
||||
values=".33 0 0 0 .33
|
||||
.5 .5 0 0 0
|
||||
.33 .33 .33 0 1
|
||||
0 0 0 1 0"/>
|
||||
<feGaussianBlur result="blurOut" in="colorOut" stdDeviation="4" />
|
||||
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
|
||||
</filter>
|
||||
|
||||
<filter id="alphaFilter" x="0" y="0" width="200%" height="200%">
|
||||
<feOffset result="offOut" in="SourceAlpha" dx="20" dy="20" />
|
||||
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="4" />
|
||||
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
|
||||
</filter>
|
||||
|
||||
<filter id="alphaColorFilter" x="0" y="0" width="200%" height="200%">
|
||||
<feOffset result="offOut" in="SourceAlpha" dx="20" dy="20" />
|
||||
<feColorMatrix type="matrix" result="colorOut" in="offOut"
|
||||
values=".33 0 0 0 .33
|
||||
.5 .5 0 0 0
|
||||
.33 .33 .33 0 1
|
||||
1 1 1 1 0"/>
|
||||
<feGaussianBlur result="blurOut" in="colorOut" stdDeviation="4" />
|
||||
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
|
||||
</filter>
|
||||
</defs>
|
||||
<g filter="url(#colorFilter)">
|
||||
<rect x="10" y="10" width="90" height="90" stroke="green" stroke-width="3"
|
||||
fill="yellow" />
|
||||
|
||||
<linearGradient id="Grad1a" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop stop-color="blue" offset="0"/>
|
||||
<stop stop-color="pink" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="Grad1b" xlink:href="#Grad1a"/>
|
||||
<rect x="20" y="170" width="100" height="80" fill="url(#Grad1a)"/>
|
||||
</g>
|
||||
|
||||
<circle fill="violet" cx="170" cy="70" r="40" filter="url(#alphaFilter)"/>
|
||||
|
||||
<linearGradient id="GradOp" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="0">
|
||||
<stop stop-color="blue" offset="0" stop-opacity="0.3"/>
|
||||
<stop stop-color="pink" offset="1" stop-opacity="1"/>
|
||||
</linearGradient>
|
||||
<rect x="150" y="200" width="90" height="90" stroke="green" stroke-width="3"
|
||||
fill="url(#GradOp)" filter="url(#alphaColorFilter)"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.4 KiB |
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="pJi-Pa-uLB">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14113" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="pJi-Pa-uLB">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
@ -162,7 +162,7 @@
|
||||
<!--SVG Example-->
|
||||
<scene sceneID="7mv-yr-foI">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="SVGExampleViewController" title="SVG Example" id="mKW-eb-P6k" customClass="SVGExampleViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<viewController storyboardIdentifier="SVGViewController" title="SVG Example" id="mKW-eb-P6k" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="TsH-he-yyr"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="Ohj-O3-2uP"/>
|
||||
@ -174,6 +174,9 @@
|
||||
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="yHP-DJ-SIl" customClass="SVGView" customModule="Macaw">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="string" keyPath="fileName" value="tiger"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@ -184,9 +187,6 @@
|
||||
<constraint firstItem="yHP-DJ-SIl" firstAttribute="top" secondItem="TsH-he-yyr" secondAttribute="bottom" id="tzO-cY-rQ9"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="svgView" destination="yHP-DJ-SIl" id="JDo-NA-VIx"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="W3h-lx-w4E" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
@ -317,10 +317,10 @@
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2006" y="470"/>
|
||||
</scene>
|
||||
<!--SVG-->
|
||||
<!--Filters-->
|
||||
<scene sceneID="79Q-Jd-PMG">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="SVGViewController" title="SVG" automaticallyAdjustsScrollViewInsets="NO" id="uvA-T8-hbw" customClass="SVGViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<viewController storyboardIdentifier="FiltersViewController" title="Filters" automaticallyAdjustsScrollViewInsets="NO" id="uvA-T8-hbw" customClass="FiltersViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="fig-Rp-T8Z"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="R8P-6y-Q4e"/>
|
||||
@ -329,46 +329,27 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="nXz-zM-57V">
|
||||
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="8gR-K6-HAF" customClass="MacawView" customModule="Macaw">
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<view key="tableFooterView" contentMode="scaleToFill" id="blh-kp-V0S">
|
||||
<rect key="frame" x="0.0" y="72" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="menu_cell" id="nqI-oj-oEY">
|
||||
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="nqI-oj-oEY" id="iuZ-Mw-Fwi">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</tableViewCellContentView>
|
||||
</tableViewCell>
|
||||
</prototypes>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="uvA-T8-hbw" id="axt-M8-Xeg"/>
|
||||
<outlet property="delegate" destination="uvA-T8-hbw" id="ybU-2C-kLl"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="nXz-zM-57V" firstAttribute="top" secondItem="fig-Rp-T8Z" secondAttribute="bottom" id="6kx-FJ-5rL"/>
|
||||
<constraint firstItem="nXz-zM-57V" firstAttribute="leading" secondItem="uKJ-4t-eHg" secondAttribute="leading" id="Gja-K9-TGl"/>
|
||||
<constraint firstAttribute="trailing" secondItem="nXz-zM-57V" secondAttribute="trailing" id="f8Z-Fh-Imv"/>
|
||||
<constraint firstItem="R8P-6y-Q4e" firstAttribute="top" secondItem="nXz-zM-57V" secondAttribute="bottom" id="g7K-hq-BDw"/>
|
||||
<constraint firstItem="8gR-K6-HAF" firstAttribute="top" secondItem="fig-Rp-T8Z" secondAttribute="bottom" id="V71-zb-YZV"/>
|
||||
<constraint firstItem="R8P-6y-Q4e" firstAttribute="top" secondItem="8gR-K6-HAF" secondAttribute="bottom" id="ge3-gq-kRo"/>
|
||||
<constraint firstAttribute="trailing" secondItem="8gR-K6-HAF" secondAttribute="trailing" id="gsv-aU-6a8"/>
|
||||
<constraint firstItem="8gR-K6-HAF" firstAttribute="leading" secondItem="uKJ-4t-eHg" secondAttribute="leading" id="iP3-MM-Aq0"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" title="Examples" id="7nX-3I-PDX"/>
|
||||
<connections>
|
||||
<outlet property="tableView" destination="nXz-zM-57V" id="sKg-c7-UXN"/>
|
||||
<outlet property="macawView" destination="8gR-K6-HAF" id="OSo-Sk-duM"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="7hP-nz-SZf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-81" y="1916"/>
|
||||
<point key="canvasLocation" x="-82.400000000000006" y="1915.5922038980511"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
|
51
Example/Example/Examples/Filters/FiltersViewController.swift
Normal file
51
Example/Example/Examples/Filters/FiltersViewController.swift
Normal file
@ -0,0 +1,51 @@
|
||||
//
|
||||
// FiltersViewController.swift
|
||||
// Example
|
||||
//
|
||||
// Created by Alisa Mylnikova on 04/06/2018.
|
||||
// Copyright © 2018 Exyte. All rights reserved.
|
||||
//
|
||||
|
||||
import Macaw
|
||||
|
||||
class FiltersViewController: UIViewController {
|
||||
|
||||
@IBOutlet weak var macawView: MacawView!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
let yellowRect = Shape(form: Rect(x: 180, y: 30, w: 90, h: 90), fill: Color.yellow, stroke: Stroke(fill: Color.green, width: 3), effect: Effect.dropShadow())
|
||||
|
||||
let stop1 = Stop(offset: 0, color: Color.blue.with(a: 0.3))
|
||||
let stop2 = Stop(offset: 1, color: Color.purple)
|
||||
let gradient = LinearGradient(stops: [stop1, stop2])
|
||||
let rect = Shape(form: Rect(x: 150, y: 200, w: 90, h: 90), fill: gradient, stroke: Stroke(fill: Color.green, width: 3))
|
||||
rect.effect = OffsetEffect(dx: 20, dy: 20).colorMatrix(
|
||||
matrix: [0.33, 0, 0, 0, 0.33,
|
||||
0.5, 0.5, 0, 0, 0,
|
||||
0.33, 0.33, 0.33, 0, 1,
|
||||
1, 1, 1, 1, 0]).blur(radius: 4).blend()
|
||||
|
||||
let circle = Shape(form: Circle(cx: 30, cy: 70, r: 50), fill: Color.navy, place: Transform(m11: 1, m12: 0, m21: 0, m22: 1, dx: 50, dy: 50))
|
||||
circle.effect = .dropShadow(dx: 10, dy: 10, radius: 5, color: .teal)
|
||||
macawView.node = Group(contents: [yellowRect, rect, circle])
|
||||
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
// Get the new view controller using segue.destinationViewController.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
//
|
||||
// SVGExampleViewController.swift
|
||||
// Example
|
||||
//
|
||||
// Created by Alisa Mylnikova on 17/05/2018.
|
||||
// Copyright © 2018 Exyte. All rights reserved.
|
||||
//
|
||||
|
||||
import Macaw
|
||||
|
||||
class SVGExampleViewController: UIViewController {
|
||||
|
||||
@IBOutlet var svgView: SVGView!
|
||||
|
||||
var fileName: String?
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
svgView.fileName = fileName
|
||||
}
|
||||
|
||||
override func didReceiveMemoryWarning() {
|
||||
super.didReceiveMemoryWarning()
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// MARK: - Navigation
|
||||
|
||||
// In a storyboard-based application, you will often want to do a little preparation before navigation
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
// Get the new view controller using segue.destinationViewController.
|
||||
// Pass the selected object to the new view controller.
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
import UIKit
|
||||
|
||||
open class SVGViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
|
||||
|
||||
@IBOutlet var tableView: UITableView!
|
||||
|
||||
fileprivate var svgExamples = [
|
||||
"shadows",
|
||||
"tiger"
|
||||
]
|
||||
|
||||
open override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
tableView.reloadData()
|
||||
}
|
||||
|
||||
open func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return svgExamples.count
|
||||
}
|
||||
|
||||
open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "menu_cell")!
|
||||
cell.textLabel?.text = svgExamples[indexPath.row].capitalized
|
||||
return cell
|
||||
}
|
||||
|
||||
open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let controller = UIStoryboard(name: "Main", bundle: .none).instantiateViewController(withIdentifier: "SVGExampleViewController") as! SVGExampleViewController
|
||||
controller.fileName = svgExamples[indexPath.row]
|
||||
navigationController?.pushViewController(controller, animated: true)
|
||||
}
|
||||
|
||||
}
|
@ -11,7 +11,8 @@ open class MenuViewController: UIViewController, UITableViewDataSource, UITableV
|
||||
"SVGViewController",
|
||||
"EasingExampleController",
|
||||
"MorphingExampleController",
|
||||
"EventsExampleController"
|
||||
"EventsExampleController",
|
||||
"FiltersViewController"
|
||||
].map {
|
||||
UIStoryboard(name: "Main", bundle: .none).instantiateViewController(withIdentifier: $0)
|
||||
}
|
||||
|
@ -7,7 +7,8 @@ open class ColorMatrixEffect: Effect {
|
||||
public init(matrix: [Double] = [1, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0], input: Effect? = nil) {
|
||||
0, 0, 0, 1, 0],
|
||||
input: Effect? = nil) {
|
||||
if matrix.count != 20 {
|
||||
fatalError("ColorMatrixEffect: wrong matrix count")
|
||||
}
|
||||
|
@ -7,7 +7,26 @@ open class Effect {
|
||||
}
|
||||
|
||||
public static func dropShadow(dx: Double = 0, dy: Double = -3, radius: Double = 3, color: Color = .black) -> Effect? {
|
||||
let blur = GaussianBlur(radius: radius, input: BlendEffect(input: nil))
|
||||
return OffsetEffect(dx: dx, dy: dy, input: ColorMatrixEffect(color: color, input: blur))
|
||||
return OffsetEffect(dx: dx, dy: dy).colorMatrix(color: color).blur(radius: radius).blend()
|
||||
}
|
||||
|
||||
public func offset(dx: Double, dy: Double) -> Effect {
|
||||
return OffsetEffect(dx: dx, dy: dy, input: self)
|
||||
}
|
||||
|
||||
public func colorMatrix(matrix: [Double]) -> Effect {
|
||||
return ColorMatrixEffect(matrix: matrix, input: self)
|
||||
}
|
||||
|
||||
public func colorMatrix(color: Color) -> Effect {
|
||||
return ColorMatrixEffect(color: color, input: self)
|
||||
}
|
||||
|
||||
public func blur(radius: Double) -> Effect {
|
||||
return GaussianBlur(radius: radius, input: self)
|
||||
}
|
||||
|
||||
public func blend() -> Effect {
|
||||
return BlendEffect(input: self)
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ open class OffsetEffect: Effect {
|
||||
open let dx: Double
|
||||
open let dy: Double
|
||||
|
||||
public init(dx: Double = 0, dy: Double = 0, input: Effect?) {
|
||||
public init(dx: Double = 0, dy: Double = 0, input: Effect? = nil) {
|
||||
self.dx = dx
|
||||
self.dy = dy
|
||||
super.init(input: input)
|
||||
|
@ -12,7 +12,7 @@ struct RenderingInterval {
|
||||
}
|
||||
|
||||
class NodeRenderer {
|
||||
|
||||
|
||||
let view: MView?
|
||||
|
||||
fileprivate let onNodeChange: () -> Void
|
||||
@ -32,7 +32,7 @@ class NodeRenderer {
|
||||
if isAnimating {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
view?.setNeedsDisplay()
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ class NodeRenderer {
|
||||
next = next?.input
|
||||
}
|
||||
let offset = dx != 0 || dy != 0 ? OffsetEffect(dx: dx, dy: dy, input: nil) : nil
|
||||
return (offset, otherEffects)
|
||||
return (offset, otherEffects.reversed())
|
||||
}
|
||||
|
||||
fileprivate func applyEffects(_ effects: [Effect], context: CGContext, opacity: Double, useAlphaOnly: Bool = false) {
|
||||
|
@ -1047,57 +1047,66 @@ open class SVGParser {
|
||||
fileprivate func parseEffect(_ filterNode: XMLIndexer) -> Effect? {
|
||||
let defaultSource = "SourceGraphic"
|
||||
var effects = [String: Effect]()
|
||||
for child in filterNode.children.reversed() {
|
||||
for child in filterNode.children {
|
||||
guard let element = child.element else { continue }
|
||||
|
||||
let filterIn = element.allAttributes["in"]?.text ?? defaultSource
|
||||
let filterOut = element.allAttributes["result"]?.text ?? ""
|
||||
let currentEffect = effects[filterOut]
|
||||
effects.removeValue(forKey: filterOut)
|
||||
let filterIn = element.allAttributes["in"]!.text
|
||||
var currentEffect = effects[filterIn]
|
||||
if currentEffect == nil && filterIn == "SourceAlpha" {
|
||||
currentEffect = AlphaEffect(input: nil)
|
||||
} else if currentEffect == nil && filterIn != defaultSource {
|
||||
fatalError("Filter parsing: Incorrect effects order")
|
||||
}
|
||||
effects.removeValue(forKey: filterIn)
|
||||
|
||||
let filterOut = element.allAttributes["result"]?.text
|
||||
var resultingEffect: Effect? = .none
|
||||
|
||||
switch element.name {
|
||||
case "feOffset":
|
||||
if let dx = getDoubleValue(element, attribute: "dx"), let dy = getDoubleValue(element, attribute: "dy") {
|
||||
effects[filterIn] = OffsetEffect(dx: dx, dy: dy, input: currentEffect)
|
||||
resultingEffect = OffsetEffect(dx: dx, dy: dy, input: currentEffect)
|
||||
}
|
||||
case "feGaussianBlur":
|
||||
if let radius = getDoubleValue(element, attribute: "stdDeviation") {
|
||||
effects[filterIn] = GaussianBlur(radius: radius, input: currentEffect)
|
||||
resultingEffect = GaussianBlur(radius: radius, input: currentEffect)
|
||||
}
|
||||
case "feColorMatrix":
|
||||
if let type = element.allAttributes["type"]?.text {
|
||||
if type == "saturate" {
|
||||
effects[filterIn] = ColorMatrixEffect(saturate: getDoubleValue(element, attribute: "values")!, input: currentEffect)
|
||||
resultingEffect = ColorMatrixEffect(saturate: getDoubleValue(element, attribute: "values")!, input: currentEffect)
|
||||
}
|
||||
if type == "hueRotate" {
|
||||
let degrees = getDoubleValue(element, attribute: "values")!
|
||||
effects[filterIn] = ColorMatrixEffect(hueRotate: degrees / 180 * Double.pi, input: currentEffect)
|
||||
resultingEffect = ColorMatrixEffect(hueRotate: degrees / 180 * Double.pi, input: currentEffect)
|
||||
}
|
||||
if type == "luminanceToAlpha" {
|
||||
effects[filterIn] = ColorMatrixEffect.luminanceToAlpha(input: currentEffect)
|
||||
resultingEffect = ColorMatrixEffect.luminanceToAlpha(input: currentEffect)
|
||||
} else { // "matrix"
|
||||
effects[filterIn] = ColorMatrixEffect(matrix: getMatrix(element, attribute: "values"), input: currentEffect)
|
||||
resultingEffect = ColorMatrixEffect(matrix: getMatrix(element, attribute: "values"), input: currentEffect)
|
||||
}
|
||||
}
|
||||
case "feBlend":
|
||||
if let filterIn2 = element.allAttributes["in2"]?.text {
|
||||
if filterIn2 == defaultSource {
|
||||
effects[filterIn] = BlendEffect(input: nil)
|
||||
} else if filterIn == defaultSource {
|
||||
effects[filterIn2] = BlendEffect(input: nil)
|
||||
if currentEffect != nil {
|
||||
resultingEffect = BlendEffect(input: currentEffect)
|
||||
} else if let currentEffect = effects[filterIn2] {
|
||||
resultingEffect = BlendEffect(input: currentEffect)
|
||||
}
|
||||
}
|
||||
default:
|
||||
print("SVG parsing error. Filter \(element.name) not supported")
|
||||
continue
|
||||
}
|
||||
|
||||
if filterOut == nil {
|
||||
return resultingEffect
|
||||
}
|
||||
effects[filterOut!] = resultingEffect
|
||||
}
|
||||
|
||||
if let effect = effects["SourceAlpha"] {
|
||||
return AlphaEffect(input: effect)
|
||||
}
|
||||
if let effect = effects[defaultSource] {
|
||||
return effect
|
||||
if effects.count == 1 {
|
||||
return effects.first?.value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user