๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS/UI

[๐Ÿงฉ Creative Coding] ์ปฌ๋Ÿฌํ’€ํ•œ ๋ฌผ๊ฒฐ ์›จ์ด๋ธŒ ๋งŒ๋“ค๊ธฐ(feat. Interactive Developer)

by Fomagran ๐Ÿ’ป 2021. 12. 16.
728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š” Foma ๐Ÿ’ป ์ž…๋‹ˆ๋‹ค!

 

์˜ค๋Š˜์€ ์ €๋ฒˆ์— ์ค„์— ๋งค๋‹ฌ๋ ค ํ”๋“ค๋ฆฌ๋Š” ์ƒ์ž ๋งŒ๋“ค๊ธฐ ์— ์ด์–ด์„œ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ๋””๋ฒจ๋กœํผ๋‹˜์˜ ํŠœํ† ๋ฆฌ์–ผ ์›€์ง์ด๋Š” ์›จ์ด๋ธŒ๋ฅผ

 

Swift๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์„ ์ •๋ฆฌํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค!

 

๋ฐ”๋กœ ์‹œ์ž‘ํ• ๊ฒŒ์š”~

 

์•„๋ž˜๋Š” ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ๋””๋ฒจ๋กœํผ ๊น€์ข…๋ฏผ๋‹˜์˜ ํŠœํ† ๋ฆฌ์–ผ ์˜์ƒ์ž…๋‹ˆ๋‹ค.

 


Preview

 


1. S์ž ๊ณก์„  ๊ทธ๋ฆฌ๊ธฐ

 

S์ž ๊ณก์„ ์„ ๊ทธ๋ฆฌ๊ธฐ ์œ„ํ•ด์„œ ์‹œ์ž‘๊ณผ ๋์„ ์ •ํ•ด์ฃผ๊ณ  ์‚ฌ์ด์— ๋‘ ์ ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ์‚ฌ์ด์˜ ์ ์„ ์œ„๋กœ ๋‹น๊ธฐ๊ฑฐ๋‚˜ ์•„๋ž˜๋กœ ๋‹น๊ฒจ์ฃผ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ S์ž ๊ณก์„ ์ด ๊ทธ๋ ค์ง‘๋‹ˆ๋‹ค.

 

 

2. ์›€์ง์ด๋Š” ์›จ์ด๋ธŒ ๋งŒ๋“ค๊ธฐ

 

์—ฐ๊ฒฐ๋œ ์„ ์˜ ์‚ฌ์ด ๋‘ ์ ์„ ์œ„ ์•„๋ž˜๋กœ ์ด๋™์‹œํ‚ค๋ฉด ์›จ์ด๋ธŒ๊ฐ€ ์›€์ง์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒ ์ฃ ?

 

 

 

 

3. ์—ฌ๋Ÿฌ ์›จ์ด๋ธŒ ๋งŒ๋“ค๊ธฐ

 

์šฐ์„  ์‹œ์ž‘๊ณผ ๋์„ ์•„๋ž˜์™€ ๊ฐ™์ด ๋‘ ์ ์œผ๋กœ ์ •ํ•ด์ค๋‹ˆ๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  ๊ทธ ์‚ฌ์ด์— ์žˆ๋Š” ์  4๊ฐœ๋ฅผ 1,2,3,4๋ผ๊ณ  ๋ถ€๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

์‚ฌ์ด์˜ ์  ๋‘ ๊ฐœ๋ฅผ ์ž„์˜๋กœ ๊ณจ๋ผ ๊ณก์„ ์„ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

1๊ณผ 3์œผ๋กœ ๊ณจ๋ž์„ ๊ฒฝ์šฐ

 

 

2์™€ 4๋กœ ๊ณจ๋ž์„ ๊ฒฝ์šฐ

 

 

1๊ณผ 4๋กœ ๊ณจ๋ž์„ ๊ฒฝ์šฐ

 


์ฝ”๋“œ ๊ตฌํ˜„

 

Line

 

์„ ์€ ์„ ์„ ๊ทธ๋ฆด CAShapeLayer์™€ ์‚ฌ์ด ๋‘ ๊ฐœ์˜ ์  p1,p2์™€ ์›จ์ด๋ธŒ๋ฅผ ์ฑ„์šธ ์ƒ‰์„ ํ”„๋กœํผํ‹ฐ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

import UIKit

struct Line {
    let layer:CAShapeLayer
    let p1:Int
    let p2:Int
    var color:UIColor
}

Point

 

์ ์€ ํ˜„์žฌ ์œ„์น˜์ธ x์™€ y

 

์ ์ด ์œ„ ์•„๋ž˜๋กœ ์ด๋™ํ•˜๋Š”๋ฐ ํ•œ๊ณ„๋ฅผ ์ •ํ•ด์ค„ max์™€ min

 

์œ„๋กœ ๊ฐˆ์ง€ ์•„๋ž˜๋กœ ๊ฐˆ์ง€๋ฅผ ์ •ํ•ด์ค„ addY๋ฅผ ํ”„๋กœํผํ‹ฐ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

import UIKit

struct Point {
    var x:CGFloat
    var y:CGFloat
    var max:CGFloat
    var min:CGFloat
    var addY:CGFloat
    var center:CGPoint {
        return CGPoint(x: x, y: y)
    }
}

WaveView

 

WaveView์— ํ•„์š”ํ•œ ํ”„๋กœํผํ‹ฐ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

class WaveView: UIView {
    
    private var timer : Timer?
    private var points:[Point] = []
    private var lines:[Line] = []
    private lazy var centerY:CGFloat = frame.height/2
    private var lineCount:Int = 3
    private var dotCount:Int = 4
    private let colors:[UIColor] = [.systemPink,.systemBlue,.systemCyan,.systemMint,.systemTeal]

 


configure

 

 

ํƒ€์ด๋จธ๋ฅผ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.

 

 

    private func configure() {
        timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(timerCallback), userInfo: nil, repeats: true)
        putDots()
        appendLines()
    }

 

๊ทธ๋ฆฌ๊ณ  ํƒ€์ด๋จธ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ๊ณก์„ ๋“ค์€ ๋‘ ์‚ฌ์ด์˜ ์ ์˜ ์œ„์น˜์— ๋งž๊ฒŒ ์—…๋ฐ์ดํŠธ ๋ฉ๋‹ˆ๋‹ค.

 

 @objc func timerCallback() {
        updateLineCuve()
    }
    
    private func updateLineCuve() {
        for i in 0..<points.count {
            points[i].y += points[i].addY
            if points[i].y > centerY + points[i].max  || points[i].y < centerY + points[i].min {
                points[i].addY = -(points[i].addY)
            }
        }
        for i in 0..<lineCount {
            addCurve(line:lines[i],p1:lines[i].p1,p2:lines[i].p2)
        }
    }

 

putDots

 

์ ์€ ๋ทฐ์˜ ๊ฐ€๋กœ๋ฅผ ์  ๊ฐฏ์ˆ˜+1๋งŒํผ์œผ๋กœ ๋‚˜๋ˆ  x๊ฐ’์„ ์ •ํ•˜๊ณ  ์ตœ๋Œ€์™€ ์ตœ์†Œ,์œ„๋กœ ๊ฐˆ์ง€ ์•„๋ž˜๋กœ ๊ฐˆ์ง€๋ฅผ ์ •ํ•ด์„œ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

private func putDots() {
        let w:CGFloat = self.bounds.width/CGFloat(dotCount+1)
        for i in 1...dotCount {
            let x:CGFloat = w*CGFloat(i)
            let max:CGFloat = CGFloat.random(in: centerY/2...centerY)
            let min:CGFloat = CGFloat.random(in: (-centerY)...(-centerY/2))
            let addY:CGFloat = CGFloat(i%2) == 0 ? -1:1
            points.append(Point(x: x, y: centerY, max: max, min: min, addY: addY))
        }
    }

 

appendLines

 

์„ ์€ ์‚ฌ์ด์˜ ๋‘ ์ ๊ณผ ์ƒ‰์„ ๋žœ๋คํ•˜๊ฒŒ ์ •ํ•ด์„œ ์›ํ•˜๋Š” ๊ฐฏ์ˆ˜๋งŒํผ ๋„ฃ์–ด์ค๋‹ˆ๋‹ค.

 

private func appendLines() {
        for _ in 0..<lineCount {
            lines.append(Line(layer:CAShapeLayer(),p1:(0..<dotCount).randomElement()!, p2:(0..<dotCount).randomElement()!, color: (colors.randomElement()!)))
        }
    }

 

addCurve

 

์•„๋ž˜์™€ ๊ฐ™์ด ๊ณก์„ ์„ p1,p2์— ๋งž๊ฒŒ ์—ฐ๊ฒฐํ•ด์ฃผ๊ณ  ๊ทธ ์•ˆ์„ ์ฑ„์šธ ์ƒ‰์„ ์ •ํ•ด์ค๋‹ˆ๋‹ค.

 

    private func addCurve(line:Line,p1:Int,p2:Int) {
        line.layer.removeFromSuperlayer()
        let height:CGFloat = self.frame.height
        let width:CGFloat = self.frame.width
        let linePath = UIBezierPath()
        linePath.move(to:CGPoint(x: 0, y:height))
        linePath.addLine(to:CGPoint(x: 0, y:height/2))
        linePath.addCurve(to:CGPoint(x: width, y:height/2), controlPoint1:points[p1].center, controlPoint2:points[p2].center)
        linePath.addLine(to: CGPoint(x: width, y: height))
        line.layer.path = linePath.cgPath
        line.layer.fillColor = line.color.withAlphaComponent(0.4).cgColor
        layer.addSublayer(line.layer)
    }

WaveViewController

 

์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋ทฐ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

 

class WaveViewController: UIViewController {
    
    var waveView:WaveView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        configure()
    }
    
    private func configure() {
        self.view.backgroundColor = UIColor(displayP3Red: 55/255, green: 55/255, blue: 55/255, alpha: 1)
        waveView = WaveView(frame:CGRect(x:self.view.center.x-150, y: self.view.center.y-130, width: 300, height: 260))
        self.view.addSubview(waveView)
    }

 

์•„๋ž˜์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ณก์„ ์ด ์›จ์ด๋ธŒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 


Source Code

 

์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ๋Š” ์•„๋ž˜ ๊นƒํ—™์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

(๋ง˜์— ๋“œ์…จ๋‹ค๋ฉด ์Šคํƒ€ ํ•œ๋ฒˆ์”ฉ๋งŒ ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š” ใ…œ)

 

 

GitHub - Art-code-club/Swift-ArtCode: Swift version ArtCode

Swift version ArtCode. Contribute to Art-code-club/Swift-ArtCode development by creating an account on GitHub.

github.com

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€