I want to create a parallax effect 3D image using depth map in flutter. The gyroscope sensor of the phone will be used to create the 3D effect when user titles. What is the logic behind this creating a parallax image and display it on screen. Thanks
I tried using the following code but gives invalid image err.
double offsetX = 0.0;
double offsetY = 0.0;
late StreamSubscription<GyroscopeEvent> gyroscopeSubscription;
@override
void initState() {
super.initState();
// Start listening to gyroscope data
gyroscopeSubscription = gyroscopeEvents.listen((GyroscopeEvent event) {
// Update the position based on gyroscope data
setState(() {
offsetX = event.y; // Adjust based on your preferred axis
offsetY = event.x; // Adjust based on your preferred axis
});
});
}
@override
void dispose() {
// Stop listening to gyroscope data when the widget is disposed
gyroscopeSubscription.cancel();
super.dispose();
}
Future<MemoryImage> createParallaxImage(String imagePath, String depthMapPath) async {
final ByteData data = await rootBundle.load(depthMapPath);
final Uint8List depthMapBytes = data.buffer.asUint8List();
final ByteData imageData = await rootBundle.load(imagePath);
final Uint8List imageBytes = imageData.buffer.asUint8List();
final Uint8List resultBytes = applyParallaxEffect(imageBytes, depthMapBytes);
return MemoryImage(resultBytes);
}
double scaleFactor = 10.0;
Uint8List applyParallaxEffect(Uint8List imageBytes, Uint8List depthMapBytes) {
// Image dimensions (adjust based on your image)
int width = 300;
int height = 300;
// Scaling factor for parallax effect
// Create a copy of the original image
Uint8List resultBytes = Uint8List.fromList(imageBytes);
// Iterate over each pixel in the image
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// Calculate the index for the current pixel
int index = (i * width + j) * 4;
// Extract intensity from the depth map
int depthIndex = (i * width + j) * 4;
int depth = depthMapBytes[depthIndex];
// Shift the pixel horizontally based on the depth
int shiftedIndex = index + depth;
if (shiftedIndex < resultBytes.length) {
resultBytes[shiftedIndex] = imageBytes[index];
resultBytes[shiftedIndex + 1] = imageBytes[index + 1];
resultBytes[shiftedIndex + 2] = imageBytes[index + 2];
resultBytes[shiftedIndex + 3] = imageBytes[index + 3];
}
}
}
return resultBytes;
}
@override
Widget build(BuildContext context) {
return Center(
child: Transform(
transform: Matrix4.translationValues(offsetX * scaleFactor, offsetY * scaleFactor, 0),
child: FutureBuilder<MemoryImage>(
future: createParallaxImage(
Images.bb1, // Replace with the path to your visible image
Images.bb1depth, // Replace with the path to your depth map
),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
return Image.memory(
snapshot.data!.bytes,
width: 300, // Adjust based on your image dimensions
height: 300, // Adjust based on your image dimensions
);
} else {
return const CircularProgressIndicator();
}
},
),
),
);
}
It's hard for me to understand what you really want without a visual reference (gif or video would be nice). But are you looking for a tilt parallax hover effect? Example can be found here:
https://amoshuke.github.io/flutter_tilt_book/#/Example
If yes, you can use the flutter_tilt package: https://pub.dev/packages/flutter_tilt