iPhoneボールペイント

ボールに絵を貼付けるiPhoneアプリのサンプルコードを描いてみます

import UIKit

import SceneKit

class ViewController: UIViewController {

    weak var scene : SCNScene?

    weak var paintView : UIView?

    weak var shape : CAShapeLayer?

    var drawColor = UIColor.whiteColor()

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        self.createPaintTool()

        self.setupScene()

        self.createCamera()

        self.createButton()

    }

    

    func createPaintTool() {

        let w = CGRectGetMaxX(self.view.bounds)

        let h = CGRectGetMidY(self.view.bounds)

        let paintv = UIView(frame: CGRect(x: 0, y: h, width: w, height: h))

        paintv.backgroundColor = UIColor(hue: 0.6, saturation: 0.8, brightness: 0.4, alpha: 1)

        self.view.addSubview(paintv)

        self.paintView = paintv

        

        for i in 0..<4 {

            let x : CGFloat = CGFloat(i) * 40 + 10

            let y = h 40 10

            let color = UIView(frame: CGRect(x: x, y: y, width: 40, height: 40))

            color.layer.cornerRadius = 20

            color.backgroundColor = UIColor(hue: CGFloat(i) * 0.2, saturation: 0.3, brightness: 1, alpha: 1)

            paintv.addSubview(color)

        }

    }

    

    func setupScene() {

        let w = CGRectGetMaxX(self.view.bounds)

        let sv = SCNView(frame: CGRectMake(0, 0, w, w))

        sv.scene = SCNScene()

        sv.backgroundColor = UIColor(hue: 0.3, saturation: 0.8, brightness: 0.7, alpha: 1)

        self.view.addSubview(sv)

        self.scene = sv.scene

        

        let box = SCNBox(width: 30, height: 1, length: 80, chamferRadius: 0)

        box.firstMaterial?.diffuse.contents = UIColor.lightGrayColor()

        let boxNode = SCNNode(geometry: box)

        boxNode.position = SCNVector3(x: 0, y: 0, z: –40)

        self.scene?.rootNode.addChildNode(boxNode)

        boxNode.physicsBody = SCNPhysicsBody.staticBody()

    }

    

    func createCamera() {

        let camera = SCNNode()

        camera.camera = SCNCamera()

        camera.camera?.zFar = 200

        camera.position = SCNVector3(x: 0, y: 10, z: 40)

        self.scene?.rootNode.addChildNode(camera)

    }

    

    func createButton() {

        let btn = UIButton.buttonWithType(.System) as UIButton

        btn.setTitle(“Go”, forState: .Normal)

        btn.titleLabel?.font = UIFont.boldSystemFontOfSize(40)

        btn.sizeToFit()

        btn.center = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds))

        self.view.addSubview(btn)

        

        btn.addTarget(self, action: “go”, forControlEvents: .TouchUpInside)

    }

    

    func go() {

        let ball = SCNSphere(radius: 10)

        

        

        UIGraphicsBeginImageContext(self.paintView!.frame.size);

        self.paintView!.layer.renderInContext(UIGraphicsGetCurrentContext());

        let screenshot = UIGraphicsGetImageFromCurrentImageContext();

        UIGraphicsEndImageContext();

        

        ball.firstMaterial?.diffuse.contents = screenshot

        let ballNode = SCNNode(geometry: ball)

        

        ballNode.physicsBody = SCNPhysicsBody.dynamicBody()

        ballNode.physicsBody?.applyForce(SCNVector3(x: 0, y: 4, z: –20), atPosition: SCNVector3(x: 0, y: 5, z: 5), impulse: true)

        ballNode.position = SCNVector3(x: 0, y: 30, z: 0)

        self.scene?.rootNode.addChildNode(ballNode)

        

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(10.0 * Double(NSEC_PER_SEC))),

            dispatch_get_main_queue(), { ballNode.removeFromParentNode() })

    }

    

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

        let p = touches.anyObject()!.locationInView(self.paintView)

        if let hit = self.paintView?.hitTest(p, withEvent: nil) {

            

            let sl = CAShapeLayer()

            sl.frame = self.paintView!.bounds

            let path = UIBezierPath()

            path.moveToPoint(p)

            sl.path = path.CGPath

            self.paintView?.layer.addSublayer(sl)

            

            if hit != self.paintView {

                // color change

                self.drawColor = hit.backgroundColor!

            }

            sl.strokeColor = self.drawColor.CGColor

            sl.fillColor = UIColor.clearColor().CGColor

            sl.lineWidth = 8

            

            self.shape = sl

        }

    }

    

    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {

        let p = touches.anyObject()!.locationInView(self.paintView)

        if let hit = self.paintView?.hitTest(p, withEvent: nil) {

            let path = CGPathCreateMutableCopy(self.shape?.path)

            CGPathAddLineToPoint(path, nil, p.x, p.y)

            self.shape?.path = path

        }

    }

}