MatchExtractsWithReference.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. <template>
  2. <ExperimentBlock
  3. :run-expe="runExpe"
  4. :calibration-check="calibrationCheck"
  5. :experiment-name="experimentName"
  6. :scene-name="sceneName"
  7. :loading-message="loadingMessage"
  8. :loading-error-message="loadingErrorMessage"
  9. >
  10. <template v-slot:header>
  11. <!-- Extract configuration -->
  12. <extract-configuration
  13. v-if="lockConfig === false"
  14. @setExtractConfig="setExtractConfig($event, $refs.configurator)"
  15. :loading-error-message="loadingErrorMessage"
  16. ref="configurator"
  17. />
  18. <!--/ Extract configuration -->
  19. </template>
  20. <template v-slot:content>
  21. <div class="text-center">
  22. <v-dialog
  23. v-model="dialogLess"
  24. v-if="explanation === false"
  25. width="500"
  26. >
  27. <v-card>
  28. <v-card-title
  29. class="headline lighten-2"
  30. primary-title
  31. >
  32. <p style="font-size:0.8em;">La qualité de cette zone est déjà à son <strong>minimum</strong></p>
  33. </v-card-title>
  34. <v-divider />
  35. <v-card-actions>
  36. <v-spacer />
  37. <v-btn
  38. color="primary"
  39. text
  40. @click="dialogLess = false"
  41. >
  42. Fermer
  43. </v-btn>
  44. </v-card-actions>
  45. </v-card>
  46. </v-dialog>
  47. </div>
  48. <div class="text-center">
  49. <v-dialog
  50. v-model="dialogMore"
  51. v-if="explanation === false"
  52. width="500"
  53. >
  54. <v-card>
  55. <v-card-title
  56. class="headline lighten-2"
  57. primary-title
  58. >
  59. <p style="font-size:0.8em;">La qualité de cette zone est déjà à son <strong>maximum</strong></p>
  60. </v-card-title>
  61. <v-divider />
  62. <v-card-actions>
  63. <v-spacer />
  64. <v-btn
  65. color="primary"
  66. text
  67. @click="dialogMore = false"
  68. >
  69. Fermer
  70. </v-btn>
  71. </v-card-actions>
  72. </v-card>
  73. </v-dialog>
  74. </div>
  75. <div class="text-center">
  76. <v-dialog
  77. v-model="dialogRefError"
  78. v-if="explanation === false"
  79. width="600"
  80. >
  81. <v-card>
  82. <v-card-title
  83. class="headline lighten-2"
  84. primary-title
  85. >
  86. <p style="font-size:0.8em;">
  87. Vous venez de cliquer sur l'image de référence. Celle-ci ne sera pas modifiée par cette action. <br /><br />
  88. L'expérience a pour objectif de régler la qualité de l'image de gauche pour qu'elle soit la plus proche de l'image de droite.
  89. </p>
  90. </v-card-title>
  91. <v-divider />
  92. <v-card-actions>
  93. <v-spacer />
  94. <v-btn
  95. color="primary"
  96. text
  97. @click="dialogRefError = false"
  98. >
  99. Fermer
  100. </v-btn>
  101. </v-card-actions>
  102. </v-card>
  103. </v-dialog>
  104. </div>
  105. <div class="text-center">
  106. <v-dialog
  107. v-model="calibrationCheck"
  108. width="600"
  109. >
  110. <v-card>
  111. <v-card-title
  112. class="headline lighten-2"
  113. primary-title
  114. >
  115. <p style="font-size:0.8em;">
  116. La scène de calibration vous est proposée de nouveau dans le but de vérifier que l'image de gauche correspond toujours à celle de droite sur votre écran actuel.
  117. <br /><br />
  118. Vous pouvez la régler de nouveau si cela est nécessaire.
  119. </p>
  120. </v-card-title>
  121. <v-divider />
  122. <v-card-actions>
  123. <v-spacer />
  124. <v-btn
  125. color="primary"
  126. text
  127. @click="calibrationCheck = false"
  128. >
  129. Fermer
  130. </v-btn>
  131. </v-card-actions>
  132. </v-card>
  133. </v-dialog>
  134. </div>
  135. <v-flex v-if="explanation === true || disableStart === true" xs12 sm12>
  136. <div style="margin-top:10%">
  137. <p v-if="disableStart === false && calibrationScene === true" style="font-size: 1.4em;">
  138. Vous allez voir des images, l'image de droite constitue toujours l'image de référence. Vous devez régler la qualité de l'image de gauche pour qu'elle soit la plus proche de l'image de droite.
  139. La première image est constituée de carré gris, c'est une partie de calibration. Si vous souhaitez régler votre écran (contraste, luminosité) vous pouvez le faire maintenant mais il vous est demandé de ne plus changer ce réglage au cours de l'expérience.
  140. Vous allez ensuite voir des scènes d'image de synthèse. Vous pouvez arrêter l'expérience quand vous souhaitez (ou faire une pause).
  141. </p>
  142. <p v-if="disableStart === true" style="margin-top:2%; color:orange; font-size: 1.4em;">
  143. <strong>Attention !</strong> L'expérience requiert un écran de résolution minimale de <strong>1920 x 1080</strong> pixels.
  144. <br />
  145. <br />
  146. Vous pouvez redimensionner la fenêtre de votre navigateur pour poursuivre l'expérience.
  147. </p>
  148. <p v-if="disableStart === false" style="margin-top:2%; color:#007acc; font-size: 1.4em;">
  149. <strong>La résolution de votre fenêtre de navigateur vous permet d'accéder à l'expérience</strong>.
  150. </p>
  151. <v-btn v-if="disableStart === true" @click="startExperiment" color="#007acc" large disabled>Poursuivre l'expérience</v-btn>
  152. <v-btn v-if="disableStart === false" @click="startExperiment" color="#007acc" large>Poursuivre l'expérience</v-btn>
  153. </div>
  154. </v-flex>
  155. <v-flex v-if="haveHelp === true" xs12 sm12>
  156. <div style="margin-top:10%">
  157. <p style="font-size: 1.4em;">
  158. Cette expérience vous propose le visuel deux images, celle de gauche considérée comme dégradée et celle de gauche, sa référence (image sans dégradation visible).
  159. <br />
  160. Vous devez régler la qualité de l'image de gauche pour qu'elle soit la plus proche de l'image de droite.
  161. </p>
  162. <br />
  163. <br />
  164. <p style="font-size: 1.4em;text-align:left">
  165. Pour cela, deux actions vous sont proposées :
  166. <br />
  167. <ul>
  168. <li> <strong>clic gauche de la souris :</strong> permet d'améliorer la qualité de l'image à l'endroit où de la dégradation vous est encore visible.</li>
  169. <li> <strong>clic droit de la souris :</strong> permet de revenir à une qualité inférieure de l'image si l'amélioration apportée n'était pas nécessaire (aucune amélioration visible apportée après clic droit).</li>
  170. </ul>
  171. </p>
  172. <v-btn @click="startExperiment" color="#007acc" large>Continuer l'expérience</v-btn>
  173. </div>
  174. </v-flex>
  175. <v-flex v-if="haveBreak === true" xs12 sm12>
  176. <div style="margin-top:10%">
  177. <p style="font-size: 1.4em;">
  178. Nous vous remercions d'avoir participé à cette expérience.
  179. Elle va nous permettre d'améliorer les calculs d'images. Si vous le souhaitez, vous pouvez revenir sur l'expérience via le <a :href="launcherURI" target="_blank">launcher</a> pour revoir de nouvelles images.
  180. </p>
  181. <v-btn @click="startExperiment" color="#007acc" large>Continuer l'expérience</v-btn>
  182. </div>
  183. <!-- Add of newsletter component -->
  184. <Newsletter />
  185. </v-flex>
  186. <v-flex v-if="runExpe === true" xs12 sm6 :style="{ 'max-width': maxWidth + 'px', 'min-width': maxWidth + 'px', 'margin-right': 20 + 'px' }">
  187. <v-card dark color="primary" :max-width="maxWidth" :min-width="maxWidth">
  188. <!-- <v-card-text class="px-0">Experiment image</v-card-text> -->
  189. <v-container class="pa-1">
  190. <template v-for="i in extractConfig.y">
  191. <v-layout row wrap :key="`row-${i}`">
  192. <v-flex
  193. v-for="(anExtract, index) in extracts.slice(extractConfig.x * (i - 1), (extractConfig.x * i))"
  194. :key="`extract-${i}-${extractConfig.x}-${extractConfig.y}-${index}-${anExtract.quality}`"
  195. class="pa-0"
  196. >
  197. <v-card flat tile class="d-flex height100">
  198. <div
  199. v-if="anExtract.loading"
  200. class="img-extract-loader"
  201. @click.right.prevent
  202. >
  203. <v-progress-circular
  204. :indeterminate="true"
  205. />
  206. </div>
  207. <v-img
  208. v-else
  209. :src="anExtract.link"
  210. @click.left.prevent="extractAction($event, anExtract)"
  211. @click.right.prevent="extractAction($event, anExtract)"
  212. class="cursor"
  213. :class="{ 'extract-hover-border': showHoverBorder === true }"
  214. @error="extractsRemovedFromServerFallback"
  215. >
  216. <template v-slot:placeholder>
  217. <v-layout fill-height align-center justify-center ma-0>
  218. <v-progress-circular indeterminate color="grey lighten-5" />
  219. </v-layout>
  220. </template>
  221. </v-img>
  222. </v-card>
  223. </v-flex>
  224. </v-layout>
  225. </template>
  226. </v-container>
  227. </v-card>
  228. </v-flex>
  229. <v-flex @click="dialogRefError = true" v-if="runExpe === true" sm6 xs12 :style="{ 'max-width': maxWidth + 'px', 'min-width': maxWidth + 'px' }">
  230. <v-card dark color="primary" :max-width="maxWidth" :min-width="maxWidth">
  231. <!-- <v-card-text>Reference image</v-card-text> -->
  232. <v-img v-if="referenceImage" :src="referenceImage" :max-height="maxHeight" :max-width="maxWidth" :min-width="maxWidth" />
  233. </v-card>
  234. </v-flex>
  235. <!-- Experiment validation button -->
  236. <v-layout v-if="runExpe === true" justify-end align-content-end>
  237. <v-text-field
  238. v-model="comment"
  239. label="Ajouter un commentaire ici"
  240. />
  241. <v-btn @click="userHelp" color="#737373" large right>Besoin d'aide ?</v-btn>
  242. <v-btn @click="userBreak" color="#cc7a00" large right>Arrêter ou faire une pause</v-btn>
  243. <v-btn @click="finishExperiment" color="#008000" large right>Valider & passer à l'image suivante</v-btn>
  244. </v-layout>
  245. <!--/ Experiment validation button -->
  246. </template>
  247. </ExperimentBlock>
  248. </template>
  249. <script>
  250. import { mapGetters } from 'vuex'
  251. import ExperimentBlock from '@/components/ExperimentBlock.vue'
  252. import ExperimentBaseExtracts from '@/mixins/ExperimentBaseExtracts'
  253. import ExtractConfiguration from '@/components/ExperimentsComponents/ExtractConfiguration.vue'
  254. import Newsletter from '@/components/ExperimentsComponents/Newsletter.vue'
  255. export default {
  256. components: {
  257. ExperimentBlock,
  258. ExtractConfiguration,
  259. Newsletter
  260. },
  261. mixins: [ExperimentBaseExtracts],
  262. data() {
  263. return {
  264. referenceImage: null,
  265. maxWidth: null,
  266. maxHeight: null,
  267. launcherURI: null,
  268. explanation: false,
  269. haveBreak: false,
  270. haveHelp: false,
  271. calibrationScene: false,
  272. runExpe: false,
  273. calibrationCheck: false,
  274. disableStart: false,
  275. dialogRefError: false
  276. }
  277. },
  278. computed: {
  279. ...mapGetters(['getHostURI', 'getAllExperimentProgress'])
  280. },
  281. async mounted() {
  282. // Load config for this scene to local state
  283. this.loadConfig()
  284. // Load progress from store into local state
  285. this.loadProgress()
  286. this.launcherURI = this.getHostURI + '/launcher/'
  287. let reference = null
  288. // Load scene data from the API
  289. await Promise.all([
  290. this.getImage('max').then(res => (reference = res)).catch(e => console.log(e)),
  291. this.getQualitiesList()
  292. ])
  293. this.referenceImage = reference.link
  294. this.maxWidth = reference.metadata.width
  295. this.maxHeight = reference.metadata.height
  296. // Load the cached configuration in the configurator component
  297. if (this.lockConfig === false) this.$refs.configurator.setDefaultConfig(this.extractConfig)
  298. // Load extracts if none were cached
  299. // if (this.extracts.length === 0)
  300. await this.setExtractConfig(this.extractConfig, this.$refs.configurator)
  301. this.saveProgress()
  302. this.loadExperimentState()
  303. // check window size
  304. this.checkWindow()
  305. window.addEventListener('resize', this.checkWindow)
  306. // check if calibration is already done
  307. if (this.sceneName === '50_shades_of_grey') {
  308. // load current user progression
  309. this.progression = this.getAllExperimentProgress()
  310. let done = this.progression[this.experimentName][this.sceneName].done
  311. // change variable state for calibration if already done
  312. if (done === true) {
  313. this.calibrationCheck = true
  314. this.runExpe = true
  315. this.explanation = false
  316. this.calibrationScene = true
  317. }
  318. }
  319. },
  320. methods: {
  321. startExperiment() {
  322. this.runExpe = true
  323. this.explanation = false
  324. this.haveBreak = false
  325. this.haveHelp = false
  326. },
  327. userBreak() {
  328. this.haveBreak = true
  329. this.explanation = false
  330. this.runExpe = false
  331. this.haveHelp = false
  332. },
  333. userHelp() {
  334. this.haveHelp = true
  335. this.haveBreak = false
  336. this.explanation = false
  337. this.runExpe = false
  338. },
  339. loadExperimentState() {
  340. this.haveHelp = false
  341. this.explanation = false
  342. this.haveBreak = false
  343. this.runExpe = false
  344. if (this.sceneName === '50_shades_of_grey') {
  345. this.explanation = true
  346. this.calibrationScene = true
  347. }
  348. else {
  349. this.runExpe = true
  350. }
  351. },
  352. checkWindow() {
  353. // check window screen size
  354. if (window.innerWidth < 1920 || window.innerHeight < 900) {
  355. this.disableStart = true
  356. this.explanation = true
  357. this.runExpe = false
  358. this.haveBreak = false
  359. this.haveHelp = false
  360. }
  361. else {
  362. this.disableStart = false
  363. }
  364. }
  365. }
  366. }
  367. </script>