Skip to content

Instantly share code, notes, and snippets.

@webserveis
Forked from dkun7944/ContentView.swift
Created July 31, 2023 15:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save webserveis/329c07ef0a5598a89058e6ebf7b78b75 to your computer and use it in GitHub Desktop.
Save webserveis/329c07ef0a5598a89058e6ebf7b78b75 to your computer and use it in GitHub Desktop.
AirDrop iOS 17 Swift.Shader Animation
//
// airdrop.metal
// Airdrop Demo
//
// Created by Daniel Kuntz on 7/30/23.
//
#include <metal_stdlib>
#include <SwiftUI/SwiftUI_Metal.h>
using namespace metal;
[[ stitchable ]] half4 airdrop(float2 position, SwiftUI::Layer layer, float t, float2 viewSize) {
float2 position_yflip = float2(position.x, viewSize.y - position.y);
float uv_y_dynamic_island_offset = 0.46;
float t2 = pow(t, 2);
float t3 = pow(t, 3);
// Normalized pixel coordinates (from 0 to 1)
float2 uv = position_yflip / viewSize;
float2 uv_stretch = float2(uv.x+((uv.x-0.5)*pow(uv.y,6)*t3*0.1), uv.y * (uv.y * pow((1-(t2*0.01)), 8.0)) + (1-uv.y) * uv.y);
uv_stretch = mix(uv, uv_stretch, smoothstep(1.1, 1.0, t));
float4 color = float4(layer.sample(uv_stretch * viewSize));
float2 bang_offset = float2(0.0);
float bang_d = 0.0;
if (t >= 1.0) {
float aT = t - 1.0;
float2 uv2 = uv;
uv2 -= 0.5;
uv2.x *= viewSize.x / viewSize.y;
uv2.x -= 0.1;
float2 uv_bang = float2(uv2.x, uv2.y);
float2 uv_bang_origin = float2(uv_bang.x, uv_bang.y-uv_y_dynamic_island_offset);
bang_d = (aT*0.16)/length(uv_bang_origin);
bang_d = smoothstep(0.09, 0.05, bang_d) * smoothstep(0.04, 0.07, bang_d) * (uv.y+0.05);
bang_offset = float2(-8.0*bang_d*uv2.x, -4.0*bang_d*(uv2.y-0.4))*0.1;
float bang_d2 = ((aT-0.085) * 0.14)/length(uv_bang_origin);
bang_d2 = smoothstep(0.09, 0.05, bang_d2) * smoothstep(0.04, 0.07, bang_d2) * (uv.y+0.05);
bang_offset += float2(-8.0*bang_d2*uv2.x, -4.0*bang_d2*(uv2.y-0.4))*-0.02;
}
float2 uv_stretch_bang = uv_stretch+bang_offset;
color = float4(layer.sample(uv_stretch_bang * viewSize));
color += bang_d*500.0 * smoothstep(1.05, 1.1, t);
float Pi = 6.28318530718 * 2;
float Directions = 60.0;
float Quality = 10.0;
float Radius = t2*0.1 * pow(uv.y, 6.0) * 0.5;
Radius *= smoothstep(1.3, 0.9, t);
Radius += bang_d*0.05;
// Blur calculations
for( float d=0.0; d<Pi; d+=Pi/Directions)
{
for(float i=1.0/Quality; i<=1.0; i+=1.0/Quality)
{
float2 blurPos = (uv_stretch_bang + float2(cos(d),sin(d))*Radius*i);
color += float4(layer.sample(blurPos*viewSize));
}
}
color /= Quality * Directions;
uv -= 0.5;
uv.x *= viewSize.x / viewSize.y;
uv.x -= 0.1;
float2 lighten_uv = float2(uv.x*0.65, uv.y - t + 0.5);
float d = smoothstep(0, 0.6, 0.1/length(lighten_uv)-uv_y_dynamic_island_offset)*0.25;
float t_smooth = smoothstep(0.0, 0.3, t);
d *= t_smooth;
color = color + float4(color.r*d, color.g*d, 0.0, 1.0); // yellow blob
float2 lighten2_uv = float2(uv.x*0.4, uv.y-uv_y_dynamic_island_offset);
float d2 = smoothstep(0, 0.5, pow(1-length(lighten2_uv), 28))*0.5;
float t2_smooth = smoothstep(0.0, 1.0, t2)*1.;
d2 *= t2_smooth;
d2 *= smoothstep(1.13, 1.0, t);
color = float4(color.rgb*(1-d2), 1.0) + float4(float3(d2), 1.0); // white blob
return half4(color);
}
//
// ContentView.swift
// Airdrop Demo
//
// Created by Daniel Kuntz on 7/30/23.
//
import SwiftUI
struct ContentView: View {
@State private var timer: Timer?
@State private var t: Float = 0.0
private let shaderFunction = ShaderFunction(library: .default, name: "airdrop")
var body: some View {
VStack {
Image("mick")
.resizable()
.aspectRatio(contentMode: .fill)
.scaleEffect(x: 1.0, y: -1.0)
.layerEffect(
Shader(function: shaderFunction,
arguments: [
.float(t),
.float2(Float(UIScreen.main.bounds.width),
Float(UIScreen.main.bounds.height))
]), maxSampleOffset: CGSize(width: 800.0, height: 800.0)
)
}
.ignoresSafeArea()
.onAppear {
timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true, block: { _ in
t = (t + 0.01).truncatingRemainder(dividingBy: 2.0)
})
}
}
}
#Preview {
ContentView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment