diff --git a/orx-shade-styles/src/demo/kotlin/DemoAllGradients01.kt b/orx-shade-styles/src/demo/kotlin/DemoAllGradients01.kt index 58196f86..41b6e59c 100644 --- a/orx-shade-styles/src/demo/kotlin/DemoAllGradients01.kt +++ b/orx-shade-styles/src/demo/kotlin/DemoAllGradients01.kt @@ -1,14 +1,18 @@ import org.openrndr.application import org.openrndr.color.ColorRGBa +import org.openrndr.color.ColorXSVa import org.openrndr.draw.isolated import org.openrndr.extensions.SingleScreenshot import org.openrndr.extra.shadestyles.* import org.openrndr.math.Polar +import org.openrndr.shape.Rectangle +import kotlin.random.Random fun main() { application { configure { width = 1000 + height = 500 } program { if (System.getProperty("takeScreenshot") == "true") { @@ -19,33 +23,40 @@ fun main() { // Create gradients with initial colors val gradients = listOf( - radialGradient(ColorRGBa.PINK, ColorRGBa.WHITE), - angularGradient(ColorRGBa.PINK, ColorRGBa.WHITE), - linearGradient(ColorRGBa.PINK, ColorRGBa.WHITE), - halfAngularGradient(ColorRGBa.PINK, ColorRGBa.WHITE) + RadialGradient(ColorRGBa.PINK, ColorRGBa.WHITE), + AngularGradient(ColorRGBa.PINK, ColorRGBa.WHITE), + NPointGradient(4, Array(4) { + ColorRGBa.PINK.shade(it / 3.0) + }), + LinearGradient(ColorRGBa.PINK, ColorRGBa.WHITE), + HalfAngularGradient(ColorRGBa.PINK, ColorRGBa.WHITE) ) extend { - gradients.forEachIndexed { i, gradient -> + gradients.forEachIndexed { gradientId, gradient -> for (column in 0 until 10) { val color1 = ColorRGBa.PINK.toHSVa().shiftHue(column * 12.0) .scaleValue(0.5).toRGBa() + val w = width.toDouble() / 10.0 + val h = height.toDouble() / gradients.size + val rect = Rectangle(column * w, gradientId * h, w, h) + + val offset = Polar((seconds + column) * 15.0, 0.3).cartesian + drawer.isolated { when (gradient) { is RadialGradient -> { gradient.color1 = color1 gradient.exponent = column / 3.0 + 0.3 gradient.length = 0.6 - gradient.offset = Polar( - (seconds + column) * 15.0, 0.3).cartesian + gradient.offset = offset } is AngularGradient -> { gradient.color1 = color1 gradient.exponent = column / 3.0 + 0.3 gradient.rotation = (seconds - column) * 10.0 - gradient.offset = Polar( - (seconds + column) * 30.0, 0.3).cartesian + gradient.offset = offset } is LinearGradient -> { gradient.color1 = color1 @@ -56,13 +67,20 @@ fun main() { gradient.color1 = color1 gradient.exponent = column / 3.0 + 0.3 gradient.rotation = (column - seconds) * 10.0 - gradient.offset = Polar( - (seconds + column) * 8.0, 0.3).cartesian + gradient.offset = offset + } + is NPointGradient -> { + // Animate points. + // We could also animate colors. + gradient.points = Array(gradient.numPoints) { + rect.center + Polar(it * 90.0 + + column * 36 - seconds * 10, + 40.0).cartesian + } } } shadeStyle = gradient - rectangle(column * width / 10.0, i * height / 4.0, - width / 10.0, height / 4.0) + rectangle(rect) } } } diff --git a/orx-shade-styles/src/demo/kotlin/DemoNPointGradient01.kt b/orx-shade-styles/src/demo/kotlin/DemoNPointGradient01.kt new file mode 100644 index 00000000..4be207a0 --- /dev/null +++ b/orx-shade-styles/src/demo/kotlin/DemoNPointGradient01.kt @@ -0,0 +1,53 @@ +import org.openrndr.application +import org.openrndr.color.ColorRGBa +import org.openrndr.color.ColorXSVa +import org.openrndr.extensions.SingleScreenshot +import org.openrndr.extra.shadestyles.NPointGradient +import org.openrndr.math.Polar +import org.openrndr.shape.ShapeContour +import kotlin.math.PI +import kotlin.math.cos + +/** + * Demonstrate using an n-point gradient. + * The gradient has 8 points in screen coordinates and 8 colors. + * The colors are fixed, the points of the gradient move. + * A contour is drawn using the same points from the gradient, + * but note that this is not necessary: you can animate the gradient + * on a static shape (a circle for example) or you can animate a shape + * with a static gradient. + */ +fun main() { + application { + program { + if (System.getProperty("takeScreenshot") == "true") { + extend(SingleScreenshot()) { + this.outputFile = System.getProperty("screenshotPath") + } + } + + val numPoints = 8 + val gradient = NPointGradient(numPoints, Array(numPoints) { + ColorXSVa(it * 360.0 / numPoints, 1.0, 1.0).toRGBa() + }) + + extend { + drawer.run { + clear(ColorRGBa.WHITE.shade(0.9)) + val t = PI * 2 * (frameCount % 300) / 300.0 + val points = Array(numPoints) { + val lfo = cos(it * PI / 2 - t) + val theta = it * 360.0 / numPoints - 22.5 * lfo + val radius = 200 + 170 * lfo + bounds.center + Polar(theta, radius).cartesian + } + gradient.points = points + shadeStyle = gradient + stroke = ColorRGBa.WHITE + strokeWeight = 4.0 + contour(ShapeContour.fromPoints(points.asList(), true)) + } + } + } + } +} \ No newline at end of file diff --git a/orx-shade-styles/src/main/kotlin/LinearGradient.kt b/orx-shade-styles/src/main/kotlin/LinearGradient.kt index c13c5230..31608420 100644 --- a/orx-shade-styles/src/main/kotlin/LinearGradient.kt +++ b/orx-shade-styles/src/main/kotlin/LinearGradient.kt @@ -11,7 +11,7 @@ import org.openrndr.math.Vector2 class LinearGradient( color0: ColorRGBa, color1: ColorRGBa, - offset: Vector2, + offset: Vector2 = Vector2.ZERO, rotation: Double = 0.0, exponent: Double = 1.0) : ShadeStyle() { diff --git a/orx-shade-styles/src/main/kotlin/NPointGradient.kt b/orx-shade-styles/src/main/kotlin/NPointGradient.kt new file mode 100644 index 00000000..f045be51 --- /dev/null +++ b/orx-shade-styles/src/main/kotlin/NPointGradient.kt @@ -0,0 +1,35 @@ +package org.openrndr.extra.shadestyles + +import org.openrndr.color.ColorRGBa +import org.openrndr.draw.ShadeStyle +import org.openrndr.extra.parameters.Description +import org.openrndr.math.Vector2 +import org.openrndr.math.Vector3 + +@Description("N-Point gradient") +class NPointGradient( + numPoints: Int, + colors: Array, + points: Array = arrayOf(Vector2.ZERO)) : ShadeStyle() { + + var numPoints: Int by Parameter() + var colors: Array by Parameter() + var points: Array by Parameter() + + init { + this.numPoints = numPoints + this.colors = colors + this.points = points + + fragmentTransform = """ + float sum = 0; + vec4 rgba = vec4(0.0); + for(int i=0; i