本质
基于系统绘画API获取绘制时的点,然后通过Socket发送出去,接收端看获取传输的点数据绘制
每绘制一笔,会触发 touchbegin->touchmove->tauchend, 也就是每一个touch周期代表一笔,每一笔由很多点组成,把每一笔加入笔数组,然后把该笔数组同步到服务器,服务器分发到客户端,客户端接收到笔数组,根据笔数组创建bezierPath,然后把该路径绘制到屏幕上。
以下是伪代码
点采集和绘制
点采集
- (void)touchesBegin:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
self.pointArray = [[NSArray allloc] init]
[self.biArray addObject:self.pointArray];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
//获取坐标
CGPoint point = [[touches anyObject] locationInView:self];
//添加点到笔画中
[[self.pointArray last] addObject:point];
//绘制
[self draw:self.biArray];
}
- (void)touchesEnd:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.biArray addObject:self.pointArray];
}
//从socket接收到的笔画数组作为参数输入
//本地绘制也一样
- (void)draw:(NSArray *)biArray {
//循环所有笔画
for (bi in biArray) {
//移动到笔画的第一个点
[bezierPath moveToPoint:bi[0]]
//循环笔画所有点
for (point in bi) {
[bezierPath addLineToPoint:point];
}
}
//绘制曲线
((CAShapeLayer *)self).path = bezierPath.CGPath;
}
点传输
//启动定时器
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkAction:)];
self.displayLink.frameInterval = 2; //苹果手机屏幕刷新率60fps,既1秒60帧。frameInterval设置为几就是几帧调用一次。这里设置2,刷新率为30fps
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- (void)displayLinkAction:(CADisplayLink *)link
{
//发送点阵数据
[self.socket writeData:pointData];
}
绘制
绘制推荐使用CAShapeLayer
DrawRect:DrawRect属于CoreGraphic框架,占用CPU,消耗性能大
CAShapeLayer:CAShapeLayer属于CoreAnimation框架,通过GPU来渲染图形,节省性能。动画渲染直接提交给手机GPU,不消耗内存
总结
整体思路就是采集点,发送点,绘制点。发送需注意发送频率,数据包大小,网络等状态,例如这里的frameInterval 可根据网络堵塞情况动态调整。可根据具体情况进行调节,把握核心思路,自由发挥就好。