swifty-creatives
- Swift製のクリエイティブコーディングフレームワーク
- SwiftUIのViewやUIViewなどとして簡単にアプリに導入することができる
- 3D描画やアニメーションなど、一通りのことはできる
- Processingライクな書き方ができる
- https://github.com/yukiny0811/swifty-creatives
続き
基本的な描画方法
Sketch1.swift
import SwiftyCreatives
//スケッチプログラムを作ります
class Sketch1: Sketch {
override func draw(encoder: SCEncoder) {
color(1, 1, 1, 1) //RGBAで色を指定
box(3, 3, 3) //Boxを幅3・高さ3・奥行き3の大きさで描画
}
}
//SwiftUIのViewとしてこのように記述します
struct ContentView: View {
var body: some View {
ZStack {
SketchView(Sketch1())
}
.background(.black) //背景は黒が映える
}
}
このように白いBoxが表示されました。デフォルトでカメラ操作がONになっているので、自由に視点を移動することができます。今回はMacOSで実行していますが、iOSやMacCatalystでも同様に動作します。
現時点(v1.11.2)で対応している図形一覧 |
---|
Box |
Rectangle |
Triangle |
Circle |
Line |
3D Model (objのみ) |
Img (画像) |
Text |
UIViewObject (UIViewのxibをそのまま3D空間に配置できます。ボタンもタップ可能。) |
Push/Popを用いた描画
Sketch2.swift
class Sketch2: Sketch {
let count = 20
override func draw(encoder: SCEncoder) {
for i in 0..<count {
color(1, Float(i) / 20, 0, 1) //色を設定
pushMatrix()
rotateY(Float.pi * 2 / Float(count) * Float(i)) //座標系をY軸を中心に回転させる
translate(10, 0, 0) //現在の座標系でx軸方向に10移動する
box(1, 1, 1) //サイズ1の立方体を描画する
popMatrix()
}
}
}
このようにリング状にBoxを配置することができました。
画像の描画
Sketch3.swift
class Sketch3: Sketch {
// 画像を読み込みます
let image = Img().load(
image: NSImage(named: "image")!.cgImage(
forProposedRect: nil,
context: nil,
hints: nil
)!
).multiplyScale(12) //サイズを縦横比を保ったまま12倍します
override func draw(encoder: SCEncoder) {
image.draw(encoder) //描画します(encoderは気にしなくて大丈夫です)
}
}
ホバーしたら色が変わる長方形
Sketch4.swift
class Sketch4: Sketch {
let rect = HitTestableRect().setColor(f4(1, 1, 1, 1)).setScale(f3(5, 5, 5))
override func draw(encoder: SCEncoder) {
rect.drawWithCache(encoder: encoder, customMatrix: getCustomMatrix()) //当たり判定を含んで描画する場合にはdraw()ではなくdrawWithCache()を用います
}
override func mouseMoved(with event: NSEvent, camera: some MainCameraBase, viewFrame: CGRect) {
let mousePos = mousePos(event: event, viewFrame: viewFrame) //マウスの座標を取得する関数が用意されています
let ray = camera.screenToWorldDirection(
screenPos: mousePos,
width: Float(viewFrame.width),
height: Float(viewFrame.height)) //カメラから飛ばすrayを作成します
//rayを使ってrectの当たり判定計算を行います
//もし当たっていたらそのワールド座標を、当たっていなかったらnilが帰ってきます
if let hitPos = rect.hitTestGetPos(origin: ray.origin, direction: ray.direction) {
rect.setColor(f4(0, 1, 0, 1)) //緑色に
} else {
rect.setColor(f4(1, 1, 1, 1)) //白色に
}
}
}
このようにマウスがホバーすると色が変わるようになりました。当たり判定はRect・UIViewObject・Box・Imgにつけることができます。
クリックすると回転する長方形
Sketch5.swift
class RotatingRect: HitTestableRect {
@SCAnimatable var rotation: Float = 0.0 //SCAnimatableラッパーをつけると簡単にアニメーションができます
}
class Sketch5: Sketch {
let rect = RotatingRect().setColor(f4(1, 1, 1, 1)).setScale(f3(5, 5, 5))
//update()は毎フレームdraw()の前に呼ばれます
override func update(camera: some MainCameraBase) {
//$rotation.update()を呼ぶことによりアニメーションする値を更新しています
//deltaTimeはその名の通り前回のフレームからの時間です。固定値でもいいですが、deltaTimeを用いるとマシンスペックによる挙動の差が少なく抑えられます
rect.$rotation.update(multiplier: deltaTime * 5)
}
override func draw(encoder: SCEncoder) {
//$rotation.animationValueに現在のアニメーション用の値が入っているので、それを用いてY軸回転させます
rotateY(rect.$rotation.animationValue)
//getCustomMatrix()はとりあえずつけておいてください
rect.drawWithCache(encoder: encoder, customMatrix: getCustomMatrix())
}
override func mouseDown(with event: NSEvent, camera: some MainCameraBase, viewFrame: CGRect) {
let mousePos = mousePos(event: event, viewFrame: viewFrame)
let ray = camera.screenToWorldDirection(
screenPos: mousePos,
width: Float(viewFrame.width),
height: Float(viewFrame.height))
if let _ = rect.hitTestGetPos(origin: ray.origin, direction: ray.direction) {
rect.rotation += Float.pi
}
}
}
このように簡単にease-outでアニメーションすることができました。
その他
長くなってしまうので別記事でまた続きを解説します。
まだ紹介していない機能 |
---|
テキストの描画 |
TextFactory |
自作クラスでSketchの関数を使う方法(SCPacket) |
PostProcessingと自作シェーダーの読み込み |
PostProcessingプリセット(角丸やBloom) |
3Dモデル |
Cameraのコンフィグ(透視投影・平行投影など) |
描画のコンフィグ(フレームレートなど) |
ブレンドモード |
UIViewObjectとxibとIBAction |
Lighting |
Fog |
swifty-creativesで作れるものの例
3Dグラフ | L-System |
---|---|
![]() |
![]() |
Boxいろいろ | Bloomエフェクト |
---|---|
![]() |
![]() |
|
関連
https://qiita.com/yukiny/items/43ff5ded25ecbe6caf22
https://qiita.com/yukiny/items/7b5692b503fc7db921d4
https://github.com/yukiny0811/swifty-creatives