1
1
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:
Yuri Strot 2018-06-07 15:00:13 +07:00 committed by GitHub
commit 9fdf3c72ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 131 additions and 204 deletions

View File

@ -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 */,

View File

@ -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

View File

@ -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>

View 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.
}
*/
}

View File

@ -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.
}
*/
}

View File

@ -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)
}
}

View File

@ -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)
}

View File

@ -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")
}

View File

@ -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)
}
}

View File

@ -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)

View File

@ -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) {

View File

@ -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
}