MatchExtractsWithReference.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  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 { getCalibrationScene } from '@/config.utils'
  252. import ExperimentBlock from '@/components/ExperimentBlock.vue'
  253. import ExperimentBaseExtracts from '@/mixins/ExperimentBaseExtracts'
  254. import ExtractConfiguration from '@/components/ExperimentsComponents/ExtractConfiguration.vue'
  255. import Newsletter from '@/components/ExperimentsComponents/Newsletter.vue'
  256. export default {
  257. components: {
  258. ExperimentBlock,
  259. ExtractConfiguration,
  260. Newsletter
  261. },
  262. mixins: [ExperimentBaseExtracts],
  263. data() {
  264. return {
  265. referenceImage: null,
  266. maxWidth: null,
  267. maxHeight: null,
  268. launcherURI: null,
  269. explanation: false,
  270. haveBreak: false,
  271. haveHelp: false,
  272. calibrationScene: false,
  273. runExpe: false,
  274. calibrationCheck: false,
  275. disableStart: false,
  276. dialogRefError: false
  277. }
  278. },
  279. computed: {
  280. ...mapGetters(['getHostURI', 'getAllExperimentProgress'])
  281. },
  282. async mounted() {
  283. // load calibration for this experiment
  284. let calibrationScene = getCalibrationScene(this.experimentName)
  285. // Load config for this scene to local state
  286. this.loadConfig()
  287. // Load progress from store into local state
  288. this.loadProgress()
  289. this.launcherURI = this.getHostURI + '/launcher/'
  290. let reference = null
  291. // Load scene data from the API
  292. await Promise.all([
  293. this.getImage('max').then(res => (reference = res)).catch(e => console.log(e)),
  294. this.getQualitiesList()
  295. ])
  296. this.referenceImage = reference.link
  297. this.maxWidth = reference.metadata.width
  298. this.maxHeight = reference.metadata.height
  299. // Load the cached configuration in the configurator component
  300. if (this.lockConfig === false) this.$refs.configurator.setDefaultConfig(this.extractConfig)
  301. // Load extracts if none were cached
  302. // if (this.extracts.length === 0)
  303. await this.setExtractConfig(this.extractConfig, this.$refs.configurator)
  304. this.saveProgress()
  305. this.loadExperimentState()
  306. // check window size
  307. this.checkWindow()
  308. window.addEventListener('resize', this.checkWindow)
  309. // check if calibration is already done
  310. if (this.sceneName === calibrationScene) {
  311. // load current user progression
  312. this.progression = this.getAllExperimentProgress()
  313. let done = this.progression[this.experimentName][this.sceneName].done
  314. // change variable state for calibration if already done
  315. if (done === true) {
  316. this.calibrationCheck = true
  317. this.runExpe = true
  318. this.explanation = false
  319. this.calibrationScene = true
  320. }
  321. }
  322. },
  323. methods: {
  324. startExperiment() {
  325. this.runExpe = true
  326. this.explanation = false
  327. this.haveBreak = false
  328. this.haveHelp = false
  329. },
  330. userBreak() {
  331. this.haveBreak = true
  332. this.explanation = false
  333. this.runExpe = false
  334. this.haveHelp = false
  335. },
  336. userHelp() {
  337. this.haveHelp = true
  338. this.haveBreak = false
  339. this.explanation = false
  340. this.runExpe = false
  341. },
  342. loadExperimentState() {
  343. this.haveHelp = false
  344. this.explanation = false
  345. this.haveBreak = false
  346. this.runExpe = false
  347. if (this.sceneName === '50_shades_of_grey') {
  348. this.explanation = true
  349. this.calibrationScene = true
  350. }
  351. else {
  352. this.runExpe = true
  353. }
  354. },
  355. checkWindow() {
  356. // check window screen size
  357. if (window.innerWidth < 1920 || window.innerHeight < 900) {
  358. this.disableStart = true
  359. this.explanation = true
  360. this.runExpe = false
  361. this.haveBreak = false
  362. this.haveHelp = false
  363. }
  364. else {
  365. this.disableStart = false
  366. }
  367. }
  368. }
  369. }
  370. </script>