قالب وردپرس درنا توس
Home / IOS Development / ios – How to get calligraphy line brush effect in swift using GraphicContext

ios – How to get calligraphy line brush effect in swift using GraphicContext



Image.for drawing I am using SwiftyDrawView

 enter image description here


Following is code snippets from SwiftyDraw

 /// Overriding draw (rect :) to stroke paths

  override open func draw (_ rect: CGRect) {
        super.draw (rect)
        guard let context: CGContext = UIGraphicsGetCurrentContext () else {return}

        for line in lines {
            context.setLineCap (.round)
            context.setLineJoin (.round)
            context.setLineWidth (line.brush.width)
            // set blend fashion so eraser actually erases stuff
            context.setBlendMode (line.brush.blendMode)
            context.setAlpha (line.brush.opacity)
            context.setStrokeColor (line.brush.color.cgColor)
            context.addPath (line.path)
            context.strokePath ()
        }
    }

// TouchBegan

 override open func touchesBegan (_ touches: Set with event: UIEvent?) {
        guard isEnabled, let touch = touches.first else {return}
        if #available (iOS 9.1
, *) {             guard allowedTouchTypes.flatMap ({$ 0.uiTouchTypes}). contains (touch.type) else {return}         }         guard delegate? .swiftyDraw (shouldBeginDrawingIn: self, using: touch) ?? true else {return}         delegate? .swiftyDraw (didBeginDrawingIn: self, using: touch)         setTouchPoints (touch, view: self)         let newLine = Line (path: CGMutablePath (),                            brush: Brush (color: brush.color, width: brush.width, opacity: brush.opacity, blendMode: brush.blendMode))         newLine.path.addPath (createNewPath ())         lines.append (newline)         drawingHistory = lines // adding a new line should also update history     }

and touchesMoved

 override open func touchesMoved (_ touches: Set with event: UIEvent?) {
        guard isEnabled, let touch = touches.first else {return}
        if #available (iOS 9.1, *) {
            guard allowedTouchTypes.flatMap ({$ 0.uiTouchTypes}). contains (touch.type) else {return}
        }
        delegate? .swiftyDraw (isDrawingIn: self, using: touch)

        updateTouchPoints (for: touch, in: self)
        let newPath = createNewPath ()
        if let currentPath = lines.last {
            currentPath.path.addPath (NEWPATH)
        }
    }

Touch ended

 override open func touchesEnded (_ touches: Set with event: UIEvent?) {
        guard isEnabled, let touch = touches.first else {return}
        delegate? .swiftyDraw (didFinishDrawingIn: self, using: touch)
    }

and touch cancel

 override open func touchesCancelled (_ touches: Set with event: UIEvent?) {
        guard isEnabled, let touch = touches.first else {return}
        delegate? .swiftyDraw (didCancelDrawingIn: self, using: touch)
    }

// and set TouchPint

 private func setTouchPoints (_ touch: UITouch, view: UIView) {
        previousPoint = touch.previousLocation (in: view)
        previousPreviousPoint = touch.previousLocation (in: view)
        currentPoint = touch.location (in: view)
    }

// and updateTouchPoints

 private func updateTouchPoints (for touch: UITouch, in view: UIView) {
        previousPreviousPoint = previousPoint
        previousPoint = touch.previousLocation (in: view)
        currentPoint = touch.location (in: view)
    }

and createNewPath

 private func createNewPath () -> CGMutablePath {
        note midPoints = getMidPoints ()
        let subPath = createSubPath (midPoints.0, mid2: midPoints.1)
        let newPath = addSubPathToPath (subPath)
        return newPath
    }

and calculateMidPoint

 private func calculateMidPoint (_p1: CGPoint, p2: CGPoint) -> CGPoint {
        return CGPoint (x: (p1.x + p2.x) * 0.5, y: (p1.y + p2.y) * 0.5);
    }

and getMidPoints

 private func getMidPoints () -> (CGPoint, CGPoint) {
        let mid1: CGPoint = calculateMidPoint (previousPoint, p2: previousPreviousPoint)
        let mid2: CGPoint = calculateMidPoint (currentPoint, p2: previousPoint)
        return (mid1, mid2)
    }

and createSubPath

 private func createSubPath (_ mid1: CGPoint, mid2: CGPoint) -> CGMutablePath {
        let subpath: CGMutablePath = CGMutablePath ()
        subpath.move (to: CGPoint (x: mid1.x, y: mid1.y))
        subpath.addQuadCurve (to: CGPoint (x: mid2.x, y: mid2.y), control: CGPoint (x: previousPoint.x, y: previousPoint.y))
        return subpath
    }

and addSubPathToPath

 private func addSubPathToPath (_ subpath: CGMutablePath) -> CGMutablePath {
        let bounds: CGRect = subpath.boundingBox
        let drawBox: CGRect = bounds.insetBy (dx: -2.0 * brush.width, dy: -2.0 * brush.width)
        self.setNeedsDisplay (drawBox)
        return subpath
    }


Source link