tags:

views:

117

answers:

2

I need a way to have a gray scale image in an ImageView and on mouse moved if the cursor position is in the ImageView bounds to show a colored spotlight on the mouse position.

I have created a sample to help you understand what I need. This sample negates the colors of a colored image on the onMouseMoved event.

package javafxapplication3;

import javafx.scene.effect.BlendMode;
import javafx.scene.Group;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.Scene;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

var spotlightX = 0.0;
var spotlightY = 0.0;
var visible = false;
var anImage = Image {
        url: "{__DIR__}picture1.jpg"
    }
Stage {
    title: "Spotlighting"
    scene: Scene {
        fill: Color.WHITE
        content: [
            Group {
            blendMode: BlendMode.EXCLUSION
            content: [
                ImageView {
                    image: anImage
                    onMouseMoved: function (me: MouseEvent) {
                        if (me.x > anImage.width - 10 or me.x < 10 or me.y > anImage.height - 10 or me.y < 10) {
                            visible = false;
                        } else {
                            visible = true;
                        }
                        spotlightX = me.x;
                        spotlightY = me.y;
                    }
                },
                Group {
                    id: "spotlight"
                    content: [
                        Circle {
                            visible: bind visible
                            translateX: bind spotlightX
                            translateY: bind spotlightY
                            radius: 60
                            fill: RadialGradient {
                                centerX: 0.5
                                centerY: 0.5
                                stops: [
                                    Stop { offset: 0.1, color: Color.WHITE },
                                    Stop { offset: 0.5, color: Color.BLACK },
                                ]
                            }
                        }
                    ]
                }
            ]
        },
    ]
    },
}

To be more specific:

  1. I want to display a colored image in grayscale mode
  2. On mouseover I want a spotlight to be colored, in contrast with the rest of the image which is going to be rendered in grayscale mode(as mentioned in requirement no.1 above). The spotlight will move in the same direction as the mouse cursor
A: 

Unfortunately I can't offer a direct answer to this, but I don't think you can achieve what you're after purely using Blend modes, hopefully someone will correct me if I'm wrong.

I would suggest exploring having both a grayscale and color version of the image, where the color image is "off-screen", then have the spotlight element refer to the portion of the color image corresponding to the same area as the on-screen grayscale image. That way it would appear as though the moveable spotlight was highlighting a portion of the grayscale image in colour. In other words, the spotlight is actually "over" the colour image, even though it's off-screen.

Matthew Hegarty
+1  A: 

Here is how I would do it. Use 2 images, one colour and one grayscale. Use a clip on the grayscale. Below is a sample code

var color:ImageView = ImageView {
    image: Image {
        url: "{__DIR__}color.jpg"
    }   
}

var x:Number = 100;
var y:Number = 100;
var grayscale:ImageView = ImageView {
    image: Image {
        url: "{__DIR__}grayscale.jpg"
    }
    clip: Circle {
        centerX: bind x
        centerY: bind y
        radius: 40
    }   
    onMouseDragged: function (e: MouseEvent): Void {
        x = e.sceneX;
        y = e.sceneY;
    }
}


Stage {
    title: "Application title"
    scene: Scene {
        width: 500
        height: 500
        content: [
            color, grayscale
        ]
    }
}
Chuk Lee
Not exactly what I was looking for but more or less you nailed it man!
DaUltimateTrooper