My Home Page
harley-xk / maliang Goto Github PK
View Code? Open in Web Editor NEWiOS painting and drawing library based on Metal. 神笔马良有一支神笔(基于 Metal 的涂鸦绘图库)
License: MIT License
iOS painting and drawing library based on Metal. 神笔马良有一支神笔(基于 Metal 的涂鸦绘图库)
License: MIT License
正好需要这方面的资料参考,刚好看到这个项目 非常棒👍
请问,这俩功能有计划更新吗?
Can I know when you are going to make availabe the remaining features? I am eagerly waiting for it?
First off thanks for sharing this great framework!
It looks like the 'registerChartlet' method is missing on the Canvas
class. So we're getting an error in the TextureElementSamples
view controller.
画布放大时,画笔画出的线条变细了。
正常情况,画布放大或缩小时,画出的线条应跟之前一样粗细
hi.~ 我又来了的~
Carthage support 一下呗?
Hi,
In my app, I want the painting to be able to detect if it reaches the edge. Its painting on PNG format with black line alpha 0.5-1, the rest are transparent.
I found that your code handles all the painting in the MaLiang podfile.
Thus, which class and method should I override so when we detect the edges, it will stop coloring. Then it will begin coloring again when getting back in. This happens even user have not lift up his/her fingers.
Or do you have a method that I can call to enable/disable painting?
Any suggestions?
Thank you for such an awesome library! Its helping me. However, a crash occurred multiple times in my console .
at let textureLoader = MTKTextureLoader(device: device!)
library version - 2.6.1
with ios version: 10.3.3 and 9.3.5
画布放大的时候,已经存在的线条是放大了的,那么我手指按下去画的新线条应该也是一样的放大才对,等缩放回去之后,一起等比缩放到原来的线条。
是不是这样才符合大家的使用习惯呢?
I followed your steps, however when I try to register a brush it gives me an error.
Thank you for your time. Also, it works fine on your example project. But I want to use it on mine so I am having difficulties.
我想把UIBezierPath的线转换成Metal绘制出来,该用什么思路去实现呢?
例如我从paintCode得到一段绘制代码:
//绘制swift logo
var bezierPath = UIBezierPath()
bezierPath.moveToPoint(CGPointMake(96.14, 86.59))
bezierPath.addCurveToPoint(CGPointMake(56.82, 94.83), controlPoint1: CGPointMake(81.83, 85.02), controlPoint2: CGPointMake(87.1, 95.75))
bezierPath.addCurveToPoint(CGPointMake(20.01, 79.31), controlPoint1: CGPointMake(42.17, 94.39), controlPoint2: CGPointMake(29.06, 87.05))
bezierPath.addCurveToPoint(CGPointMake(5.25, 62.38), controlPoint1: CGPointMake(10.35, 71.06), controlPoint2: CGPointMake(5.25, 62.38))
bezierPath.addCurveToPoint(CGPointMake(35.2, 74.85), controlPoint1: CGPointMake(5.25, 62.38), controlPoint2: CGPointMake(17.28, 72.33))
bezierPath.addCurveToPoint(CGPointMake(64.02, 69.54), controlPoint1: CGPointMake(53.11, 77.37), controlPoint2: CGPointMake(64.02, 69.54))
bezierPath.addCurveToPoint(CGPointMake(37.43, 44.73), controlPoint1: CGPointMake(64.02, 69.54), controlPoint2: CGPointMake(49.91, 58.13))
bezierPath.addCurveToPoint(CGPointMake(14.97, 16.34), controlPoint1: CGPointMake(24.96, 31.34), controlPoint2: CGPointMake(14.97, 16.34))
bezierPath.addCurveToPoint(CGPointMake(40.56, 37.05), controlPoint1: CGPointMake(14.97, 16.34), controlPoint2: CGPointMake(31.85, 30.51))
bezierPath.addCurveToPoint(CGPointMake(56.82, 47.75), controlPoint1: CGPointMake(45.62, 40.86), controlPoint2: CGPointMake(56.82, 47.75))
bezierPath.addCurveToPoint(CGPointMake(43.08, 32.22), controlPoint1: CGPointMake(56.82, 47.75), controlPoint2: CGPointMake(47.12, 37.33))
bezierPath.addCurveToPoint(CGPointMake(27.99, 11.26), controlPoint1: CGPointMake(37.51, 25.17), controlPoint2: CGPointMake(27.99, 11.26))
bezierPath.addCurveToPoint(CGPointMake(55.05, 35.46), controlPoint1: CGPointMake(27.99, 11.26), controlPoint2: CGPointMake(45.04, 27.34))
bezierPath.addCurveToPoint(CGPointMake(78.26, 52.03), controlPoint1: CGPointMake(61.79, 40.93), controlPoint2: CGPointMake(78.26, 52.03))
bezierPath.addCurveToPoint(CGPointMake(80.71, 31.34), controlPoint1: CGPointMake(78.26, 52.03), controlPoint2: CGPointMake(81.63, 45.61))
bezierPath.addCurveToPoint(CGPointMake(69.08, 3), controlPoint1: CGPointMake(79.8, 17.06), controlPoint2: CGPointMake(69.08, 3))
bezierPath.addCurveToPoint(CGPointMake(97.29, 34.58), controlPoint1: CGPointMake(69.08, 3), controlPoint2: CGPointMake(89.12, 14.76))
bezierPath.addCurveToPoint(CGPointMake(100.25, 67.8), controlPoint1: CGPointMake(105.45, 54.4), controlPoint2: CGPointMake(100.25, 67.8))
bezierPath.addCurveToPoint(CGPointMake(107.29, 81.07), controlPoint1: CGPointMake(100.25, 67.8), controlPoint2: CGPointMake(104.47, 72.3))
bezierPath.addCurveToPoint(CGPointMake(107.96, 96.25), controlPoint1: CGPointMake(110.12, 89.84), controlPoint2: CGPointMake(107.96, 96.25))
bezierPath.addCurveToPoint(CGPointMake(96.14, 86.59), controlPoint1: CGPointMake(107.96, 96.25), controlPoint2: CGPointMake(105.27, 87.59))
bezierPath.closePath()
我想把这个图形,使用MaLiang的库绘制出来,还请大神指点一下。
通过 storyboard 直接拉 view 创建的话,画画就有反应。
创建 view 的代码如下:
let vvv = Canvas(frame: .zero)
vvv.frame = UIScreen.main.bounds
view.addSubview(vvv)
Reproduce steps:
Hi,
I have problem using the classes defined in MaLiang.
I have installed the pods and imported MaLiang inside the project.
Then I have make sure that the Maliang folder is in my project's Pod folder. This much is working.
But for some unknown reason, the Canvas class cannot be detected properly. It doesn't show the Canvas(frame:CGRect). Also the Brush is different and Bundle has conflict, not with my code but with some core codes from Xcode. I have tried Clean and re-build, also reinstall pods. All doesn't work
Do you know whats wrong?
Is there a way to import and export canvas data directly to NSData. Right now the import and export type is to a file in the documents directory. This support is to allow saving the canvas to database persistence stores like core data or realm.
This is my initial attempt:
public static func contentData(from canvas: Canvas) -> NSData? {
do {
let encoder = JSONEncoder()
let data = canvas.data
let content = CanvasContent(lineStrips: data?.elements.compactMap { $0 as? LineStrip } ?? [],
chartlets: data?.elements.compactMap { $0 as? Chartlet } ?? [])
let contentData = try encoder.encode(content)
return contentData as NSData
} catch {
print(error.localizedDescription)
return nil
}
}
public static func importData(value: NSData, to canvas: Canvas) {
if value.length > 0 {
let decoder = JSONDecoder()
DispatchQueue(label: "com.maliang.importing").async {
do {
let content = try decoder.decode(CanvasContent.self, from: value as Data)
/// import elements to canvas
content.lineStrips.forEach { $0.brush = canvas.findBrushBy(name: $0.brushName) }
content.chartlets.forEach { $0.canvas = canvas }
canvas.data.elements = (content.lineStrips + content.chartlets).sorted(by: { $0.index < $1.index})
DispatchQueue.main.async {
/// redraw must be call on main thread
canvas.redraw()
}
} catch {
DispatchQueue.main.async {
print(error.localizedDescription)
}
}
}
}
}
though not completely successful as the canvas isn't loading properly from the saved data.
一个纹理作为背景,然后我在背景上进行涂鸦,在保存图片的时候,只截取还有涂鸦部分的背景图呢?
the brush strokes are not smooth, when the pointStep is 1 or less. How do you make the strokes smooth on the edges of the lines?
Hi @Harley-xk
I am using your library into my project its awesome but I need one thing more that is missing in this library . just like texture rotation can we build brush painting rotation and selection from one place to other .
you can see selection tool in this library.
https://github.com/Asana/Drawsana
Thanks in advance.
Hi, I got an error when building the files even before using the class or method at all. This is just after installing pods.
My MaLiang version is 1.1.3
The error is:
"Initializer 'init(target:action:)' with Objective-C selector 'initWithTarget:action:' conflicts with implicit initializer 'init(target:action:)' from superclass 'UIPanGestureRecognizer' with the same Objective-C selector"
如题,我尝试把前一个画板的数据,恢复到下个画板上的时候,发现路径线条都变成了黑色?
是有什么共享了数据导致的么?
直接冷启动,恢复数据是没问题的。
OpenGL ES 在ios 12上已经被标记为废弃了的。
https://developer.apple.com/ios/whats-new/
Deprecation of OpenGL ES
Apps built using OpenGL ES will continue to run in iOS 12, but OpenGL ES is deprecated in iOS 12. Games and graphics-intensive apps that previously used OpenGL ES should now adopt Metal.
Metal is designed from the ground up to provide the best access to the modern GPUs on iOS, macOS, and tvOS devices. Metal avoids the overhead inherent in legacy technologies and exposes the latest graphics processing functionality. Unified support for graphics and compute in Metal lets your apps efficiently utilize the latest rendering techniques. For information about developing apps and games using Metal, see the developer documentation for Metal, Metal Performance Shaders, and MetalKit.
When I change to eraser mode ,the brush is not round ,
but the texture image 'point.png' is round,
then I change eraser color to red
can see the red round with white border
for some reason when you write W's on canvas it doesn't render properly compared to alternative drawing programs. This is in particular when you try to write small W's. Only the last stroke for the w is registered giving it a V shape instead of a W.
For example, this is how it appears in the demo app:
and this is how w's show up in paper:
Do you know what the issue is and how it might be resolved?
Hi,
I think the current context must be set to nil in deinit
deinit {
:
if EAGLContext.current() === context {
// EAGLContext.setCurrent(context)
EAGLContext.setCurrent(nil)
}
}
频繁操作的情况下,撤销功能crash了的。 日志如下:
#0. Crashed: com.apple.main-thread
0 Fun Draw 0x100a01264 _T08Fun_Draw6MLViewC7textureSQyAA9MLTextureCGvWTf4dn_n (MLView.swift:65)
1 Fun Draw 0x1009dfbdc Canvas.redraw() -> () (Canvas.swift:115)
2 Fun Draw 0x100a08e14 specialized SketchpadViewController.actionForUndo(UIButton) -> () + 4378856980
3 Fun Draw 0x100a0491c @objc SketchpadViewController.actionForUndo(UIButton) -> () + 4378839324
4 UIKitCore 0x1b1957ec0 -[UIApplication sendAction:to:from:forEvent:] + 96
5 UIKitCore 0x1b1a7ccdc -[UIControl sendAction:to:forEvent:] + 80
6 UIKitCore 0x1b1a7cffc -[UIControl _sendActionsForEvents:withEvent:] + 440
7 UIKitCore 0x1b1a7bffc -[UIControl touchesEnded:withEvent:] + 568
8 UIKitCore 0x1b20f43e0 -[UIWindow _sendTouchesForEvent:] + 2472
9 UIKitCore 0x1b20f5644 -[UIWindow sendEvent:] + 3156
10 UIKitCore 0x1b1971fa4 -[UIApplication sendEvent:] + 340
11 UIKitCore 0x1b18adb34 __dispatchPreprocessedEventFromEventQueue + 1440
12 UIKitCore 0x1b18b05a0 __handleEventQueueInternal + 4740
13 UIKitCore 0x1b18a9134 __handleHIDEventFetcherDrain + 152
14 CoreFoundation 0x1853365b8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
15 CoreFoundation 0x185336538 __CFRunLoopDoSource0 + 88
16 CoreFoundation 0x185335e1c __CFRunLoopDoSources0 + 176
17 CoreFoundation 0x185330ce8 __CFRunLoopRun + 1040
18 CoreFoundation 0x1853305b8 CFRunLoopRunSpecific + 436
19 GraphicsServices 0x1875a1584 GSEventRunModal + 100
20 UIKitCore 0x1b19567ac UIApplicationMain + 212
21 Fun Draw 0x1009b5e6c main (AppDelegate.swift:14)
22 libdyld.dylib 0x184df0c0c start + 4
Hi MaLiang,
This is very helpful.But when I'm trying to draw lines with pen, but not connected two line. It only recognizes every second stroke and does not start writing at exact point of contact. When I'm zooming then it's more skip point instead of start point.
Please help me ASAP. Please review attached screenshot for understand issues.
Thank You MaLiang.
我在学习ios 的opengl技术,我想请教下,为什么我在比较快的情况下画笔会出现丢笔的情况
It looks like the one of the recent updates broke the pencil, brush and claw brushes. There's no output on those strokes.
用这个库,实现在图片上涂鸦的功能,应该怎么做
这里提示内存地址错误:
glTexImage2D(GL_TEXTURE_2D.gluint, 0, GL_RGBA, gl_width.int32, gl_height.int32, 0, GL_RGBA.gluint, GL_UNSIGNED_BYTE.gluint, gl_data)
How do you achieve perfect straight lines? Any tips or suggestions would be helpful.
Thank You!
请问一下,为什么初始化调用的时候一直闪退呢?
logo:
[4690:2837285] Metal GPU Frame Capture Enabled
[4690:2837285] Metal API Validation Enabled
[4690:2837285] -[MTLRenderPipelineDescriptorInternal validateWithDevice:], line 2395: error 'vertexFunction must not be nil.'
-[MTLRenderPipelineDescriptorInternal validateWithDevice:]:2395: failed assertion `vertexFunction must not be nil.'
调用:
lazy var canvas: Canvas = {
let canvas = Canvas.init(frame: CGRect.init(x: 0, y: 0, width: 500, height: 500))
return canvas
}()
how about if I want draw some glow style lines,i need to change pipelineState? or renderPassDescriptor
Hello Harley,
Please review attached video, I am facing problem when zoomed and drawing very sort line(draw line in " v" shape), then some times got only tap gesture instead of pan gesture.
It's working normal zoom mode, getting issues when zoom in only
DrawingDemo Issues video.mov.zip
.
Please help me.
Thanks and Regards
Rahul
Hi, dear.
use_frameworks!
target 'MaLiang_Example' do
pod 'Comet'
pod 'MaLiang'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Extensions/UIAlertController+Comet.swift:13:64: 'Style' is not a member type of 'UIAlertAction'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Extensions/UIBarButtonItem+Closure.swift:17:69: 'Style' is not a member type of 'UIBarButtonItem'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:92:91: Type 'UIResponder' has no member 'keyboardWillShowNotification'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:94:90: Type 'UIResponder' has no member 'keyboardDidShowNotification'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:95:98: Type 'UIResponder' has no member 'keyboardWillChangeFrameNotification'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:149:42: Type 'UIResponder' has no member 'keyboardAnimationDurationUserInfoKey'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Extensions/UIVIew+Comet.swift:65:98: 'OptionsKey' is not a member type of 'UINib'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:150:26: Type 'UIView' has no member 'AnimationOptions'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:167:34: Type 'UIResponder' has no member 'keyboardFrameEndUserInfoKey'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Classes/KeyboardManager.swift:180:22: Type 'UIView' has no member 'AnimationOptions'
MaLiang-1.1.8/Example/Pods/Comet/Comet/Extensions/UINavigationBar+Comet.swift:27:59: Type 'NSAttributedString' has no member 'Key'
...
Would you help me, please ?
Thanks.
新开 issue,渐进恢复数据问题集中在这里讨论
This is more of a request than an issue, but is there a technique for locking the max opacity of a stroke to a given value?
For example, say I set the brush opacity to 0.25 and the pointStep to 1. The individual samples render with an opacity of 0.25 but as they overlap it quickly goes up to 1.0.
Do you have any ideas of how I can reliably keep the max opacity at a given value?
您好,在iPhone X上发现一个很奇怪的bug:
发现问题卡在第三步,如果直接缩放的比例非常小,由于设置了最小缩放???,所以手松开会回弹一下到稍微大一点的比例,然后再进行绘制,就会丢失之前的数据,如果是正常慢慢缩小没问题的。
您觉得是什么原因导致的呢?
烦请及时更新
我现在已经在oc项目桥接上了。但是好像没有类和方法暴露
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.