Igis Snippet: Maintaining a Constant Aspect Ratio

From Coder Merlin
Revision as of 10:52, 27 January 2020 by Yarsenius (talk | contribs) (Created page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Within these castle walls be forged Mavens of Computer Science ...
— Merlin, The Coder

Rendering a Frame with a Constant Aspect Ratio[edit]

import Igis

class Painter : PainterBase {

    let frame : Path
    let frameWidth : Double = 1200
    let frameHeight : Double = 700
    let blackFillStyle = FillStyle(color:Color(.black))
    let frameFillStyle = FillStyle(color:Color(.white))

    var scaleTransform = Transform()
    var offsetTransform = Transform()
    var windowSize : Size?

    required init() {
        let frameWidthInt = Int(frameWidth)
        let frameHeightInt = Int(frameHeight)
        frame = Path(fillMode:.fill)
        frame.moveTo(Point())
        frame.lineTo(Point(x:frameWidthInt, y:0))
        frame.lineTo(Point(x:frameWidthInt, y:frameHeightInt))
        frame.lineTo(Point(x:0, y:frameHeightInt))
        frame.close()
    }

    override func onWindowResize(size:Size) {
        windowSize = size
    }

    func calculateTransforms(canvas:Canvas) {
        if let newCanvasSize = windowSize {
            canvas.canvasSetSize(size:newCanvasSize)

            let newCanvasWidth = Double(newCanvasSize.width)
            let newCanvasHeight = Double(newCanvasSize.height)

            if newCanvasWidth / newCanvasHeight >= frameWidth / frameHeight {
                let scale = newCanvasHeight / frameHeight
                let offset = (newCanvasWidth - frameWidth * scale) * 0.5
                offsetTransform = Transform(translate:DoublePoint(x:offset, y:0), mode:.fromIdentity)
                scaleTransform = Transform(scale:DoublePoint(x:scale, y:scale), mode:.fromCurrent)
            } else {
                let scale = newCanvasWidth / frameWidth
                let offset = (newCanvasHeight - frameHeight * scale) * 0.5
                offsetTransform = Transform(translate:DoublePoint(x:0, y:offset), mode:.fromIdentity)
                scaleTransform = Transform(scale:DoublePoint(x:scale, y:scale), mode:.fromCurrent)
            }

            windowSize = nil
        }
    }

    override func render(canvas:Canvas) {
        calculateTransforms(canvas:canvas)
        if let canvasSize = canvas.canvasSize {
            canvas.render(Transform())
            let canvasRect = Rect(topLeft:Point(), size:canvasSize)
            let canvasRectangle = Rectangle(rect:canvasRect, fillMode:.fill)
            canvas.render(blackFillStyle, canvasRectangle, offsetTransform, scaleTransform, frameFillStyle, frame, Clip())
            // Render everything else
        }
    }
}

print("Starting...")
do {
    let igis = Igis()
    try igis.run(painterType:Painter.self)
} catch (let error) {
    print("Error: \(error)")
}