Skip to content

Intout Submission. (Mert Tecimen) #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
82 changes: 82 additions & 0 deletions Fire Animation.swiftpm/ContentView + ViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
//
// ContentView + ViewModel.swift
// Fire Animation
//
// Created by Mert Tecimen on 7.09.2022.
//

import Foundation
import SwiftUI

extension ContentView{
class ViewModel: ObservableObject{
var fuseSegments: [CGPoint]
var radialGradient: RadialGradient
var largeRadialGradient: RadialGradient
@Published var xOffset: CGFloat
@Published var yOffset: CGFloat
@Published var rotationDegree: CGFloat
@Published var isFuseVisible: Bool
@Published var textColor: Color = .white
var fuseDelay: Double

init(fuseDelay: Double = 1.0){
self.xOffset = 0.5
self.yOffset = 0
fuseSegments = []
let duoGradient = Gradient(colors: [.yellow, .black])
self.radialGradient = .radialGradient(duoGradient, center: .center, startRadius: 10, endRadius: 50)
self.largeRadialGradient = .radialGradient(duoGradient, center: .center, startRadius: 0, endRadius: 300)
self.rotationDegree = 0
self.fuseDelay = fuseDelay
self.isFuseVisible = true
generateFuseSegments()
}

private func generateFuseSegments(){
for index in 0..<Int.random(in: 10...20){
fuseSegments.append(.init(
x: CGFloat.random(
in: (0.05 * CGFloat((index/100)))...0.95
),
y: CGFloat.random(
in: 0.05...0.95)
)
)
}
// Bottom mid end point
fuseSegments.append(CGPoint(x: 0.5, y: 1.0))
}

func animate(index: Int = 0, size: CGSize){
if fuseSegments.count == index{
withAnimation(.easeOut(duration: 0.5)){
self.isFuseVisible = false
}
return
}
rotateFuseView(pointCoef: fuseSegments[index], size: size)
withAnimation(.linear(duration: self.fuseDelay)){
xOffset = self.fuseSegments[index].x
yOffset = self.fuseSegments[index].y
}
DispatchQueue.main.asyncAfter(deadline: .now() + self.fuseDelay){ [unowned self] in
animate(index: index+1, size: size)
}
}

func rotateFuseView(pointCoef: CGPoint, size: CGSize){
let start = CGPoint(
x: size.width * xOffset,
y: size.height * yOffset
)
let end = CGPoint(
x: size.width * pointCoef.x,
y: size.height * pointCoef.y
)
let slope = atan2(start.y - end.y, start.x - end.x) * 180/Double.pi
self.rotationDegree = 90 + slope
}

}
}
53 changes: 53 additions & 0 deletions Fire Animation.swiftpm/ContentView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import SwiftUI

struct ContentView: View {

@Binding var isStarted: Bool
@StateObject private var viewModel = ViewModel()

var body: some View {
GeometryReader { geometry in
Text("Tap to Start")
.foregroundColor(viewModel.textColor)
.position(x: geometry.size.width / 2, y: geometry.size.height / 2)
.onAppear{
withAnimation(.easeIn(duration: 1).repeatForever(autoreverses: true)){
viewModel.textColor = .orange
}
}
.opacity(!isStarted ? 1 : 0)
ZStack(alignment: .topLeading) {
// Uncommnet to see randomly generated fuse path:
//FusePathView(width: geometry.size.width, height: geometry.size.height, fuseSegments: viewModel.fuseSegments, strokeColor: .white)
ZStack{
Circle()
.fill(viewModel.radialGradient)
FuseView()
.rotationEffect(Angle(degrees: viewModel.rotationDegree))
.frame(width: 25, height: 25)

}
.opacity((viewModel.isFuseVisible && isStarted) ? 1 : 0)
.position(x: geometry.size.width * viewModel.xOffset, y: geometry.size.height * viewModel.yOffset)
.frame(width: 100, height: 100)
if !viewModel.isFuseVisible{
ZStack{
Circle()
.fill(viewModel.largeRadialGradient)
.frame(width: geometry.size.width, height: geometry.size.height)
FireView()
.transition(.scale)
.frame(width: geometry.size.width / 1.1, height: geometry.size.height / 1.5)

}
.position(x: geometry.size.width / 2, y: geometry.size.height/1.5)
}


}
.onChange(of: isStarted){ _ in
viewModel.animate(size: geometry.size)
}
}
}
}
141 changes: 141 additions & 0 deletions Fire Animation.swiftpm/FireView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
//
// FireView.swift
// Fire Animation
//
// Created by Mert Tecimen on 7.09.2022.
//

import SwiftUI

struct FlameShape: Shape, Animatable{

private var x: CGFloat = 0.5
private var y: CGFloat = 0

var animatableData: AnimatablePair<CGFloat, CGFloat>{
get{ .init(x, y) }
set{
x = newValue.first
y = newValue.second
}
}

init(animatableData: AnimatablePair<CGFloat, CGFloat> = .init(0.5, 0) ) {
self.animatableData = animatableData
}


func path(in rect: CGRect) -> Path {
return Path { path in

path.move(to: .init(
x: rect.width * x,
y: rect.height * y)
)

path.addCurve(
to: .init(
x: rect.width * 1,
y: rect.height * 0.7
),
control1: .init(
x: rect.width * 0.6,
y: rect.height * 0
),
control2: .init(
x: rect.width * 0.9,
y: rect.height * 0.5
)
)

path.addCurve(
to: .init(
x: rect.width * 0.5,
y: rect.height * 1
),
control1: .init(
x: rect.width * 1,
y: rect.height * 0.7
), control2: .init(
x: rect.width * 1,
y: rect.height * 1
)
)

path.addCurve(
to: .init(
x: rect.width * 0,
y: rect.height * 0.7
),
control1: .init(
x: rect.width * 0,
y: rect.height * 1
), control2: .init(
x: rect.width * 0,
y: rect.height * 0.7
)
)



path.addCurve(
to: .init(
x: rect.width * x,
y: rect.height * y
),
control1: .init(
x: rect.width * 0.1,
y: rect.height * 0.5
), control2: .init(
x: rect.width * 0.40,
y: rect.height * 0
)
)




}
}

}

struct FireView: View {
@State private var flameMotion: AnimatablePair<CGFloat, CGFloat> = .init(0.5, 0)
let timer = Timer.publish(every: 0.2, on: .main, in: .default).autoconnect()
var body: some View {
GeometryReader{ geometry in
ZStack(alignment: .topLeading){

FlameShape(animatableData: .init(flameMotion.first * CGFloat.random(in: 0.5...1.5), flameMotion.second * CGFloat.random(in: -0.5...1)))
.fill(Color.orange)
.opacity(0.6)
.rotationEffect(Angle(degrees: -10), anchor: .init(x: 0, y: 0.7))
.offset(.init(width: 0, height: 0.35 * geometry.size.height))
.frame(width: geometry.size.width / 2, height: geometry.size.height / 2)

FlameShape(animatableData: flameMotion)
.fill(Color.orange)
.frame(width: geometry.size.width, height: geometry.size.height)
.onReceive(timer){ _ in
withAnimation(.linear(duration: 0.2)){
flameMotion = .init(CGFloat.random(in: 0.2...0.7), CGFloat.random(in: -0.2...0))
}
}

FlameShape(animatableData: flameMotion)
.fill(Color.yellow)
.offset(.init(width: geometry.size.width / 4, height: 0.35 * geometry.size.height))
.frame(width: geometry.size.width / 2, height: geometry.size.height / 2)


}
}
}
}

struct FireView_Previews: PreviewProvider {
static var previews: some View {
FireView()
}
}
46 changes: 46 additions & 0 deletions Fire Animation.swiftpm/FusePathView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// FusePathView.swift
// Fire Animation
//
// Created by Mert Tecimen on 7.09.2022.
//

import SwiftUI

struct FusePathView: View {

let width: CGFloat
let height: CGFloat
let fuseSegments: [CGPoint]
let strokeColor: Color

init(width: CGFloat, height: CGFloat, fuseSegments: [CGPoint], strokeColor: Color = .black) {
self.width = width
self.height = height
self.fuseSegments = fuseSegments
self.strokeColor = strokeColor
}

var body: some View {
Path { path in
// Top middle start point.
path.move(
to: CGPoint(
x: width * 0.5,
y: height * 0.0
)
)

fuseSegments.forEach { segment in
path.addLine(
to: CGPoint(
x: width * segment.x,
y: height * segment.y
)
)
}
}
.stroke(strokeColor)
}
}

55 changes: 55 additions & 0 deletions Fire Animation.swiftpm/FuseView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// FuseView.swift
// Fire Animation
//
// Created by Mert Tecimen on 6.09.2022.
//

import SwiftUI

struct FuseView: View {
@State private var scaleFactor1: CGSize = .init(width: 1, height: 1)
@State private var scaleFactor2: CGSize = .init(width: 0.5, height: 0.5)
@State private var rotationDegree: CGFloat = 0

var body: some View {
GeometryReader { geometry in
ZStack() {
Circle()
.foregroundColor(.orange)
.scaleEffect(scaleFactor2)
.offset(y: -geometry.size.width * 1.7)
Circle()
.foregroundColor(.orange)
.scaleEffect(scaleFactor1)
.offset(y: -geometry.size.width * 1)
ZStack{
Circle()
.foregroundColor(.orange)
Circle()
.foregroundColor(.yellow)
.frame(width: geometry.size.width * 4/6)
}

}

.frame(width: geometry.size.width)
.onAppear{
withAnimation(.linear(duration: 0.6).repeatForever(autoreverses: false).delay(0)){
self.scaleFactor1 = .init(width: 0.1, height: 0.1)
}
withAnimation(.linear(duration: 0.6).repeatForever(autoreverses: false).delay(0.1)){
self.scaleFactor2 = .init(width: 0.1, height: 0.1)
}
}
}

}

}

struct FuseView_Previews: PreviewProvider {
static var previews: some View {
FuseView()
}
}
Loading