Multiplatform canvas.
Canvas can be configured via Gradle Kotlin DSL as follows:
plugins {
id("com.android.application") // or id("com.android.library")
kotlin("multiplatform")
}
repositories {
mavenCentral()
}
kotlin {
androidTarget()
jvm()
sourceSets {
val commonMain by getting {
dependencies {
implementation("com.juul.krayon:kanvas:$version")
}
}
}
}
android {
// ...
}
repositories {
mavenCentral()
}
dependencies {
implementation("com.juul.krayon:kanvas-$platform:$version")
}
Where $platform
represents (should be replaced with) the desired platform dependency (e.g. jvm
).
Consuming Krayon for Apple targets (MacOS, iOS) requires additional setup, due to the inability to load multiple Kotlin libraries to Swift/Objective-C. The intended technique is for Krayon to be included directly by another Kotlin library which would contain shared application code, including shared Krayon drawing. That library would then export Krayon as part of its native library for use by iOS.
Include the cocoapods plugin in your Kotlin module:
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
}
When defining your framework, make sure to export Krayon modules as needed:
cocoapods {
// ...
framework {
// ...
export("com.juul.krayon:$module:$version")
}
}
A simpler, but experimental, approach involves using the Kotlin Artifacts DSL.
kotlinArtifacts {
Native.XCFramework("YourLibrary") {
targets(macosArm64, macosX64, iosArm64)
modes(DEBUG, RELEASE)
addModule("com.juul.krayon:$module:$version")
}
}
The basic building block of Krayon for Apple is the CGContextKanvas
, which allows drawing through
Krayon's multiplatform interface with Core Graphics' native drawing primitives. Krayon assumes the
DeviceRGB
colorspace. For offscreen rendering, you can create your own:
// Define some constants. Here `scale` is used to handle retina 2x scaling
let width = 400
let height = 300
let scale = 2
// Create a context and pass it to Krayon
var cgContext: CGContext = CGContext(
data: nil,
width: width * scale,
height: height * scale,
bitsPerComponent: 8,
bytesPerRow: 0,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue
)!
cgContext.scaleBy(x: scale, y: scale)
// Note that Kanvas uses the unscaled size, which does not match the pixel count of the CGContext
let kanvas = CGContextKanvas(ptr: &cgContext, width: width, height: height)
Drawing to your Krayon canvas directly from Swift isn't recommend -- the API is quite ugly. From here,
you should call a Kotlin function that handles drawing for you. As an example, using the element
module, you might simply have yourRootElement.draw(kanvas: kanvas)
.