iOS 波浪曲線的繪製
iOS 波浪曲線的繪製
還是先上圖:
其實之前就一直想看一下 iOS 關於曲線繪製的相關類容,但由於剛剛步入職場,事情比較多。所以也沒什麼時間來看這些。剛好前段時間有空看了下,做了個 Demo,就上面那個左右搖擺的頭像。由於現在是在一家外包公司,也不追求什麼炫酷的特效,之前有個做 Android 的同事說研究這些純粹是浪費時間,但是我覺得吧,其實並不是這樣的,像我們 iOS 和 Android 做前端開發的, 80%的時間是在寫介面,還是很有必要了解一下這些影象究竟是如何展現在螢幕上的,我們又該如何去控制顯示的內容呢?
其實這方面的資料有很多,網上一搜一大把,主要還是要花時間去看。我們要分清楚 UIView 和 CALayer 之間的區別和聯絡,這裡我就不細說了,好了,步入正題:如何完成上圖所展示的效果呢?
讓我們來分解一下:要實現上圖的效果要實現哪些東西:
- 實現一個波浪曲線
- 加入一個頭像,並根據曲線的浮動調整頭像的位置
- 更具曲線的切線斜率調整頭像的左右偏移
只需要完成上面三個步驟,這個效果就實現了。首先,我們來看第一個:如何實現一個波浪曲線。
實現一個波浪曲線
像這樣的一條曲線,肯定是需要我們手動去繪製的,然後設定一個定時器,再去繪製它下一次出現的位置,但是我們該如何去繪製這樣的波浪曲線呢?
仔細看一下,這個曲線是不是很眼熟?是的,就是我們高中還是初中所學的正弦曲線,來想一下正弦曲線是怎麼畫的。
在想一下通式:y=Asin(wx+u)+K 對就是這麼簡單,那引數代表的又是什麼呢?
- A :振幅
- w :角速度 w = 2PI/T T:週期
- u :初相
- K :y 軸偏移
有了這個公式,我們又該如何在螢幕上繪製正弦曲線呢?
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, 0, 0);
CGFloat y = 0.0f;
for (float x = 0.f; x <= self.width; x++) {
y = self.A1 * sin(self.w*x + self.u1) + self.K1;
CGPathAddLineToPoint(path, nil, x, y);
x++;
}
CGPathAddLineToPoint(path, nil, self.width, self.height);
CGPathAddLineToPoint(path, nil, 0, self.height);
CGPathCloseSubpath(path);
self.waveLayer1.path = path;
CGPathRelease(path);
Build 執行一下,是不是就有了一個正弦曲線呢?接下來就要讓正弦曲線動起來,這就要設定定時器去重繪這條曲線了。
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(wave)];
[displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- (void)wave {
offset += self.offsetX;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, 0, (self.A1*sin(offset + self.u1) + self.K1));
CGFloat y = 0.0f;
for (float x = 0.f; x <= self.width; x++) {
y = self.A1 * sin(self.w*x + offset + self.u1) + self.K1;
CGPathAddLineToPoint(path, nil, x, y);
x++;
}
CGPathAddLineToPoint(path, nil, self.width, self.height);
CGPathAddLineToPoint(path, nil, 0, self.height);
CGPathCloseSubpath(path);
self.waveLayer1.path = path;
CGPathRelease(path);
}
offset : 波浪曲線的初始偏移量
offsetX : 波浪曲線每次重新整理偏移量
再附一個引數初始化:
- (void)initData {
self.A1 = 8;
self.K1 = 80;
self.u1 = M_PI*3/8.0f;
self.offsetX = 0.03;
offset = 0;
self.w = M_PI/180;
}
這樣波浪曲線就完成了。
新增頭像
初始化一個 UIImageView 放在螢幕中間,每次重新整理波浪曲線的時候,都去改變頭像位置
- (void)wave {
offset += self.offsetX;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, 0, (self.A1*sin(offset + self.u1) + self.K1));
CGFloat y = 0.0f;
for (float x = 0.f; x <= self.width; x++) {
y = self.A1 * sin(self.w*x + offset + self.u1) + self.K1;
CGPathAddLineToPoint(path, nil, x, y);
x++;
}
if (self.floatImageView != nil) {
y = self.A1 * sin(self.w*(self.width/2.0 ) + offset + self.u1) + self.K1;
self.floatImageView.centerY = y - 30;
}
CGPathAddLineToPoint(path, nil, self.width, self.height);
CGPathAddLineToPoint(path, nil, 0, self.height);
CGPathCloseSubpath(path);
self.waveLayer1.path = path;
CGPathRelease(path);
}
頭像偏移
關於頭像的偏移,這裡需要算出頭像偏移角度,也就是與 X 軸的夾角。我們需要先算出正弦曲線在中間點的斜率。關於切線斜率怎麼求呢? 高數老師告訴你:對函式求導後 x 處的值為斜率。那麼對 y=Asin(wx+u)+K 求導:
y`= Awcos(wx + u)
獲得螢幕中心的斜率為 k, 根據公式 k = tana
角度:a = arctank
這個角度便是我們需要的頭像的偏移角度了,加在迴圈裡面,每次再改變頭像的角度。
- (void)wave {
offset += self.offsetX;
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, 0, (self.A1*sin(offset + self.u1) + self.K1));
CGFloat y = 0.0f;
for (float x = 0.f; x <= self.width; x++) {
y = self.A1 * sin(self.w*x + offset + self.u1) + self.K1;
CGPathAddLineToPoint(path, nil, x, y);
x++;
}
if (self.floatImageView != nil) {
y = self.A1 * sin(self.w*(self.width/2.0 ) + offset + self.u1) + self.K1;
self.floatImageView.centerY = y - 30;
CGFloat angel = atan(self.A1*(M_PI/60)*cos(self.w*(ScreenWidth/2.0f) + offset + self.u1));
self.floatImageView.transform = CGAffineTransformMakeRotation(angel / M_PI);
}
CGPathAddLineToPoint(path, nil, self.width, self.height);
CGPathAddLineToPoint(path, nil, 0, self.height);
CGPathCloseSubpath(path);
self.waveLayer1.path = path;
CGPathRelease(path);
}
搞定!
相關文章
- canvas繪製sin正弦曲線Canvas
- 怎麼用java繪製曲線Java
- 解析csv資料繪製曲線圖
- ROC曲線繪製與AUC計算
- JavaScript繪製sin正弦函式曲線JavaScript函式
- JavaScript 繪製sin正弦函式曲線JavaScript函式
- Origin教程:DSC曲線的描述和繪製
- 用canvas繪製一個曲線動畫——深入理解貝塞爾曲線Canvas動畫
- ios股票K線圖的繪製iOS
- 函式的遞迴及科赫曲線繪製函式遞迴
- flutter 自定義view 繪製曲線統計圖FlutterView
- webGL入門-四階貝塞爾曲線繪製Web
- html5中canvas繪製貝塞爾曲線HTMLCanvas
- caffe的python介面繪製loss和accuracy曲線示例Python
- MPAndroidChart繪製曲線圖、柱狀圖總結Android
- canvas繪製貝濟埃曲線程式碼例項Canvas線程
- html5中canvas貝塞爾曲線繪製菊花HTMLCanvas
- WPF隨筆收錄-實時繪製心率曲線
- 包教包會-貝塞爾曲線的繪製原理與應用
- 使用canvas繪製dribble風格水波浪Canvas
- 自定義View合輯(6)-波浪(貝塞爾曲線)View
- 基於 matplotlib 的抽象網格和能量曲線繪製程式抽象
- iOS使用Charts框架繪製折線圖iOS框架
- Flutter 自定義元件之貝塞爾曲線畫波浪球Flutter元件
- pyqt5+matplotlib繪製動態雙y軸曲線QT
- WPF開發隨筆收錄-心電圖曲線繪製
- OpenGL實現Hermite演算法繪製三次曲線MIT演算法
- Unity3d 繪製並獲取通過任意點的曲線Unity3D
- 基於react的錄音及音訊曲線繪製的元件開發React音訊元件
- iOS股票K線圖、分時圖繪製iOS
- 基於canvas實現波浪式繪製圖片Canvas
- Android日常學習:OpenGL 實踐之貝塞爾曲線繪製Android
- R語言ggsurvplot繪製生存曲線報錯 : object of type ‘symbol‘ is not subsettableR語言ObjectSymbol
- 自定義 View 梳理:用貝塞爾曲線繪製酷炫輪廓背景View
- C# Chart控制元件,chart、Series、ChartArea曲線圖繪製的重要屬性C#控制元件
- iOS UI繪製原理iOSUI
- iOS 繪製圓角iOS
- canvas 繪製線條Canvas