Spaces:
Running
Running
Commit
·
f49e1ff
1
Parent(s):
c443340
added Haptic feedback on touch collision
Browse files
client/android/app/build.gradle
CHANGED
|
@@ -47,7 +47,8 @@ android {
|
|
| 47 |
applicationId "com.example.hapticlink"
|
| 48 |
// You can update the following values to match your application needs.
|
| 49 |
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
| 50 |
-
minSdkVersion flutter.minSdkVersion
|
|
|
|
| 51 |
targetSdkVersion flutter.targetSdkVersion
|
| 52 |
versionCode flutterVersionCode.toInteger()
|
| 53 |
versionName flutterVersionName
|
|
|
|
| 47 |
applicationId "com.example.hapticlink"
|
| 48 |
// You can update the following values to match your application needs.
|
| 49 |
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
|
| 50 |
+
// minSdkVersion flutter.minSdkVersion
|
| 51 |
+
minSdkVersion 19
|
| 52 |
targetSdkVersion flutter.targetSdkVersion
|
| 53 |
versionCode flutterVersionCode.toInteger()
|
| 54 |
versionName flutterVersionName
|
client/android/app/src/main/AndroidManifest.xml
CHANGED
|
@@ -1,5 +1,6 @@
|
|
| 1 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
| 2 |
package="com.example.hapticlink">
|
|
|
|
| 3 |
<application
|
| 4 |
android:label="hapticlink"
|
| 5 |
android:name="${applicationName}"
|
|
|
|
| 1 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
| 2 |
package="com.example.hapticlink">
|
| 3 |
+
<uses-permission android:name="android.permission.VIBRATE"/>
|
| 4 |
<application
|
| 5 |
android:label="hapticlink"
|
| 6 |
android:name="${applicationName}"
|
client/lib/HomeScreen.dart
CHANGED
|
@@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
|
| 2 |
import 'package:flutter/services.dart'; // for going in fullscreen mode
|
| 3 |
import 'package:flutter/scheduler.dart'; // to add scheduler for touch collision detection
|
| 4 |
|
| 5 |
-
|
| 6 |
import 'package:shared_preferences/shared_preferences.dart';
|
| 7 |
|
| 8 |
import 'package:web_socket_channel/web_socket_channel.dart';
|
|
@@ -10,6 +9,8 @@ import 'package:web_socket_channel/status.dart' as status;
|
|
| 10 |
|
| 11 |
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
| 12 |
|
|
|
|
|
|
|
| 13 |
import "dart:convert";
|
| 14 |
import "dart:async";
|
| 15 |
|
|
@@ -38,10 +39,12 @@ class HomeScreenState extends State<HomeScreen>{
|
|
| 38 |
|
| 39 |
late Timer sendTouchScheduler;
|
| 40 |
|
| 41 |
-
double touchsize=
|
| 42 |
double touchX = 0,touchY=0;
|
| 43 |
bool isTouching=false;
|
| 44 |
|
|
|
|
|
|
|
| 45 |
late List<String> roomidList,roomnameList;
|
| 46 |
String currRoomId="",currRoomName="";
|
| 47 |
String username="";
|
|
@@ -72,8 +75,8 @@ class HomeScreenState extends State<HomeScreen>{
|
|
| 72 |
"id": "string",
|
| 73 |
},
|
| 74 |
"position": {
|
| 75 |
-
"x": 200,
|
| 76 |
-
"y": 200,
|
| 77 |
},
|
| 78 |
"color": "ff2244bb", // Hex value.
|
| 79 |
"intensity": 1, // Vibration intensity.
|
|
@@ -506,14 +509,53 @@ class HomeScreenState extends State<HomeScreen>{
|
|
| 506 |
// print("x:"+x.toString()+"\ty:"+y.toString());
|
| 507 |
// print("dx:"+dx.toString()+"\tdy:"+dy.toString());
|
| 508 |
if (dx<=touchsize && dy<=touchsize){
|
| 509 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 510 |
}
|
| 511 |
-
// else{
|
| 512 |
-
// print("No Touch Collision.");
|
| 513 |
-
// }
|
| 514 |
}
|
| 515 |
}
|
| 516 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 517 |
void detectTouchStart(DragStartDetails details){
|
| 518 |
// we have to stop see touch out of touch area
|
| 519 |
// print(details.localPosition);
|
|
@@ -560,14 +602,18 @@ class HomeScreenState extends State<HomeScreen>{
|
|
| 560 |
// print(profileColor);
|
| 561 |
// print(details.globalPosition);
|
| 562 |
|
| 563 |
-
// // detect Collision
|
| 564 |
-
// SchedulerBinding.instance.addPostFrameCallback((_) {
|
| 565 |
-
// detectTouchCollision();
|
| 566 |
-
// });
|
| 567 |
}
|
| 568 |
|
|
|
|
|
|
|
| 569 |
void detectTouchEnd(DragEndDetails details){
|
| 570 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 571 |
setState(() {
|
| 572 |
touchX = 0;
|
| 573 |
touchY = 0;
|
|
|
|
| 2 |
import 'package:flutter/services.dart'; // for going in fullscreen mode
|
| 3 |
import 'package:flutter/scheduler.dart'; // to add scheduler for touch collision detection
|
| 4 |
|
|
|
|
| 5 |
import 'package:shared_preferences/shared_preferences.dart';
|
| 6 |
|
| 7 |
import 'package:web_socket_channel/web_socket_channel.dart';
|
|
|
|
| 9 |
|
| 10 |
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
| 11 |
|
| 12 |
+
import 'package:vibration/vibration.dart'; // for the haptics
|
| 13 |
+
|
| 14 |
import "dart:convert";
|
| 15 |
import "dart:async";
|
| 16 |
|
|
|
|
| 39 |
|
| 40 |
late Timer sendTouchScheduler;
|
| 41 |
|
| 42 |
+
double touchsize=100;
|
| 43 |
double touchX = 0,touchY=0;
|
| 44 |
bool isTouching=false;
|
| 45 |
|
| 46 |
+
bool hasCollided=false;
|
| 47 |
+
|
| 48 |
late List<String> roomidList,roomnameList;
|
| 49 |
String currRoomId="",currRoomName="";
|
| 50 |
String username="";
|
|
|
|
| 75 |
"id": "string",
|
| 76 |
},
|
| 77 |
"position": {
|
| 78 |
+
"x": 200.0,
|
| 79 |
+
"y": 200.0,
|
| 80 |
},
|
| 81 |
"color": "ff2244bb", // Hex value.
|
| 82 |
"intensity": 1, // Vibration intensity.
|
|
|
|
| 509 |
// print("x:"+x.toString()+"\ty:"+y.toString());
|
| 510 |
// print("dx:"+dx.toString()+"\tdy:"+dy.toString());
|
| 511 |
if (dx<=touchsize && dy<=touchsize){
|
| 512 |
+
|
| 513 |
+
if(hasCollided==false){
|
| 514 |
+
// Collision Started
|
| 515 |
+
print("Touch Collision started");
|
| 516 |
+
|
| 517 |
+
startHapticFeedback();
|
| 518 |
+
|
| 519 |
+
setState(() {
|
| 520 |
+
hasCollided=true;
|
| 521 |
+
});
|
| 522 |
+
}
|
| 523 |
+
}
|
| 524 |
+
else{
|
| 525 |
+
|
| 526 |
+
if(hasCollided==true){
|
| 527 |
+
// collision ended
|
| 528 |
+
print("Touch Collision ended");
|
| 529 |
+
|
| 530 |
+
endHapticFeedback();
|
| 531 |
+
|
| 532 |
+
setState(() {
|
| 533 |
+
hasCollided=false;
|
| 534 |
+
});
|
| 535 |
+
}
|
| 536 |
+
// print("No Touch Collision.");
|
| 537 |
}
|
|
|
|
|
|
|
|
|
|
| 538 |
}
|
| 539 |
}
|
| 540 |
|
| 541 |
+
void startHapticFeedback() async{
|
| 542 |
+
try{
|
| 543 |
+
if (await Vibration.hasVibrator()==true) {
|
| 544 |
+
Vibration.vibrate(pattern:[100,100,20], repeat: 1); // short fast
|
| 545 |
+
// Vibration.vibrate(pattern:[100, 200, 400],repeat: 1); // slow
|
| 546 |
+
}
|
| 547 |
+
}
|
| 548 |
+
catch(e){}
|
| 549 |
+
}
|
| 550 |
+
void endHapticFeedback() async{
|
| 551 |
+
try{
|
| 552 |
+
if (await Vibration.hasVibrator()==true) {
|
| 553 |
+
Vibration.cancel();
|
| 554 |
+
}
|
| 555 |
+
}
|
| 556 |
+
catch(e){}
|
| 557 |
+
}
|
| 558 |
+
|
| 559 |
void detectTouchStart(DragStartDetails details){
|
| 560 |
// we have to stop see touch out of touch area
|
| 561 |
// print(details.localPosition);
|
|
|
|
| 602 |
// print(profileColor);
|
| 603 |
// print(details.globalPosition);
|
| 604 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 605 |
}
|
| 606 |
|
| 607 |
+
|
| 608 |
+
|
| 609 |
void detectTouchEnd(DragEndDetails details){
|
| 610 |
|
| 611 |
+
// detect Collision end
|
| 612 |
+
detectTouchCollision(
|
| 613 |
+
x:0,
|
| 614 |
+
y:0,
|
| 615 |
+
);
|
| 616 |
+
|
| 617 |
setState(() {
|
| 618 |
touchX = 0;
|
| 619 |
touchY = 0;
|
client/macos/Flutter/GeneratedPluginRegistrant.swift
CHANGED
|
@@ -5,8 +5,10 @@
|
|
| 5 |
import FlutterMacOS
|
| 6 |
import Foundation
|
| 7 |
|
|
|
|
| 8 |
import shared_preferences_foundation
|
| 9 |
|
| 10 |
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|
|
|
| 11 |
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
| 12 |
}
|
|
|
|
| 5 |
import FlutterMacOS
|
| 6 |
import Foundation
|
| 7 |
|
| 8 |
+
import device_info_plus
|
| 9 |
import shared_preferences_foundation
|
| 10 |
|
| 11 |
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
| 12 |
+
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
| 13 |
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
| 14 |
}
|
client/pubspec.lock
CHANGED
|
@@ -57,6 +57,22 @@ packages:
|
|
| 57 |
url: "https://pub.dev"
|
| 58 |
source: hosted
|
| 59 |
version: "3.0.3"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
fake_async:
|
| 61 |
dependency: transitive
|
| 62 |
description:
|
|
@@ -325,6 +341,14 @@ packages:
|
|
| 325 |
url: "https://pub.dev"
|
| 326 |
source: hosted
|
| 327 |
version: "2.1.4"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 328 |
web_socket_channel:
|
| 329 |
dependency: "direct main"
|
| 330 |
description:
|
|
@@ -341,6 +365,14 @@ packages:
|
|
| 341 |
url: "https://pub.dev"
|
| 342 |
source: hosted
|
| 343 |
version: "4.1.4"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
xdg_directories:
|
| 345 |
dependency: transitive
|
| 346 |
description:
|
|
|
|
| 57 |
url: "https://pub.dev"
|
| 58 |
source: hosted
|
| 59 |
version: "3.0.3"
|
| 60 |
+
device_info_plus:
|
| 61 |
+
dependency: transitive
|
| 62 |
+
description:
|
| 63 |
+
name: device_info_plus
|
| 64 |
+
sha256: "7035152271ff67b072a211152846e9f1259cf1be41e34cd3e0b5463d2d6b8419"
|
| 65 |
+
url: "https://pub.dev"
|
| 66 |
+
source: hosted
|
| 67 |
+
version: "9.1.0"
|
| 68 |
+
device_info_plus_platform_interface:
|
| 69 |
+
dependency: transitive
|
| 70 |
+
description:
|
| 71 |
+
name: device_info_plus_platform_interface
|
| 72 |
+
sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
|
| 73 |
+
url: "https://pub.dev"
|
| 74 |
+
source: hosted
|
| 75 |
+
version: "7.0.0"
|
| 76 |
fake_async:
|
| 77 |
dependency: transitive
|
| 78 |
description:
|
|
|
|
| 341 |
url: "https://pub.dev"
|
| 342 |
source: hosted
|
| 343 |
version: "2.1.4"
|
| 344 |
+
vibration:
|
| 345 |
+
dependency: "direct main"
|
| 346 |
+
description:
|
| 347 |
+
name: vibration
|
| 348 |
+
sha256: "63d4f6b03e38d106599da18e786d5edcd02354433a4ed478fccbbcfc347193ab"
|
| 349 |
+
url: "https://pub.dev"
|
| 350 |
+
source: hosted
|
| 351 |
+
version: "1.8.3"
|
| 352 |
web_socket_channel:
|
| 353 |
dependency: "direct main"
|
| 354 |
description:
|
|
|
|
| 365 |
url: "https://pub.dev"
|
| 366 |
source: hosted
|
| 367 |
version: "4.1.4"
|
| 368 |
+
win32_registry:
|
| 369 |
+
dependency: transitive
|
| 370 |
+
description:
|
| 371 |
+
name: win32_registry
|
| 372 |
+
sha256: "1c52f994bdccb77103a6231ad4ea331a244dbcef5d1f37d8462f713143b0bfae"
|
| 373 |
+
url: "https://pub.dev"
|
| 374 |
+
source: hosted
|
| 375 |
+
version: "1.1.0"
|
| 376 |
xdg_directories:
|
| 377 |
dependency: transitive
|
| 378 |
description:
|
client/pubspec.yaml
CHANGED
|
@@ -12,6 +12,7 @@ dependencies:
|
|
| 12 |
sdk: flutter
|
| 13 |
flutter_colorpicker: ^1.0.3
|
| 14 |
shared_preferences: ^2.2.2
|
|
|
|
| 15 |
web_socket_channel: ^2.4.0
|
| 16 |
|
| 17 |
dev_dependencies:
|
|
|
|
| 12 |
sdk: flutter
|
| 13 |
flutter_colorpicker: ^1.0.3
|
| 14 |
shared_preferences: ^2.2.2
|
| 15 |
+
vibration: ^1.8.3
|
| 16 |
web_socket_channel: ^2.4.0
|
| 17 |
|
| 18 |
dev_dependencies:
|