1/** 2 * jQuery RoomView by Artlogic 3 * 4 * Copyright 2018, Artlogic Media Ltd, http://www.artlogic.net/ 5 */ 6 7 8;( function( $, window, document, undefined ) { 9 10 "use strict"; 11 12 // Create the defaults once 13 var pluginName = "roomView", 14 defaults = { 15 furniture_type: "chair", // Options: 'chair', 'measure', 'leathersofa' 16 wall_type: "standard", // Options: 'standard', 'concrete', 'brick' 17 floor_type: "standard", // Options: 'standard', 'wood' 18 hanging_height_cm: 140, // Runs horizontally through the * middle * of the work 19 custom_room_html: null, 20 verbose_mode: false, 21 minimum_top_margin: 150, 22 minimum_left_margin: 50, 23 hanging_ratio: 0.30, 24 floor_height: 100, 25 26 before_open: function() {} 27 }; 28 29 // Furniture settings 30 31 var defaults = $.extend( {}, defaults, { 32 default_furniture_item: 'chair', 33 furniture_items: { 34 // 'chair': { 35 // classname_suffix: 'chair', 36 // furniture_width_cm: 85 37 // }, ///OLD WHITE CHAIR 38 'bench': { 39 classname_suffix: 'bench', 40 furniture_width_cm: 300 41 }, 42 'chair': { 43 classname_suffix: 'chair', 44 furniture_width_cm: 148 45 }, 46 // 'chair2': { 47 // classname_suffix: 'chair2', 48 // furniture_width_cm: 85 49 // }, 50 'chair2': { 51 classname_suffix: 'chair2', 52 furniture_width_cm: 148 53 }, 54 'mobler_chair': { 55 classname_suffix: 'mobler_chair', 56 furniture_width_cm: 122 57 }, 58 'madsens_chair': { 59 classname_suffix: 'madsens_chair', 60 furniture_width_cm: 140 61 }, 62 'raffles_sofa': { 63 classname_suffix: 'raffles_sofa', 64 furniture_width_cm: 340, 65 artwork_minimum_floor_clearance: 200 66 }, 67 'chesterfield_sofa': { 68 classname_suffix: 'chesterfield_sofa', 69 furniture_width_cm: 350, 70 artwork_minimum_floor_clearance: 200 71 }, 72 'leathersofa': { 73 classname_suffix: 'leathersofa', 74 furniture_width_cm: 350, 75 artwork_minimum_floor_clearance: 200 76 }, 77 'measure': { 78 classname_suffix: 'measure', 79 furniture_width_cm: 200 80 }, 81 'custom_chair': { 82 classname_suffix: 'custom_chair', 83 furniture_width_cm: 148 84 } 85 } 86 }); 87 88 // The actual plugin constructor 89 function Plugin ( element, options ) { 90 this.element = element; 91 92 this.settings = $.extend( {}, defaults, options ); 93 94 if (this.settings.furniture_type && this.settings.furniture_type in this.settings.furniture_items) { 95 var furniture_settings = this.settings.furniture_items[this.settings.furniture_type]; 96 furniture_settings['id'] = this.settings.furniture_type; 97 } else { 98 var furniture_settings = this.settings.furniture_items[this.settings.default_furniture_item]; 99 furniture_settings['id'] = this.settings.default_furniture_item; 100 } 101 this.settings = $.extend({}, this.settings, { 102 furniture_settings: furniture_settings 103 }); 104 105 this._defaults = defaults; 106 this._name = pluginName; 107 this.init(); 108 } 109 110 // Avoid Plugin.prototype conflicts 111 $.extend( Plugin.prototype, { 112 init: function() { 113 114 var instance = this; 115 var element = this.element; 116 var $roomview_element = $(this.element); 117 118 //Ensure that the init class is cleared if someone hammers refresh 119 $roomview_element.removeClass('roomview-initialised'); 120 121 // Check that the image has loaded 122 // (.one so the event handler doesn't run more than once) 123 $roomview_element.one("load", function() { 124 if (instance.settings.verbose_mode == true) { 125 console.log('image loaded, running setup'); 126 } 127 128 instance.setup(instance, $roomview_element); 129 }).each(function() { 130 if(this.complete) $(this).load(); 131 }); 132 133 }, 134 setup: function(instance, $roomview_element) { 135 136 instance.inject_room(instance, $roomview_element); 137 instance.create_placeholder_artwork(instance, $roomview_element); 138 instance.button(instance, $roomview_element); 139
140 //////TODO MAKE THIS BETTER///////////////// 141 $( window ).resize(function() { 142 if ($('body.roomview-active').length ){ 143 console.log('removeClass room-css-transitions'); 144 $('img.roomview-image').removeClass('room-css-transitions'); 145 var $roomview_element = $('.roomview-image.roomview-active-element'); 146 var $roomview_room = $('[data-roomview-element-id="' + $roomview_element.attr('data-roomview-id') + '"]'); 147 148 instance.scale_artwork(instance, $roomview_element, $roomview_room); 149 150 // Scale the wrapper if the image doesnt fit in the viewport 151 instance.scale_wrapper(instance, $roomview_element, $roomview_room); 152 } 153 }); 154 var resizeTimer; 155 $(window).on('resize', function(e) { 156 clearTimeout(resizeTimer); 157 resizeTimer = setTimeout(function() { 158 if ($('body.roomview-active').length ){ 159 console.log('removeClass room-css-transitions'); 160 $('img.roomview-image').removeClass('room-css-transitions'); 161 var $roomview_element = $('.roomview-image.roomview-active-element'); 162 var $roomview_room = $('[data-roomview-element-id="' + $roomview_element.attr('data-roomview-id') + '"]'); 163 164 instance.scale_artwork(instance, $roomview_element, $roomview_room); 165 166 // Scale the wrapper if the image doesnt fit in the viewport 167 instance.scale_wrapper(instance, $roomview_element, $roomview_room); 168 } 169 }, 300); 170 });
171 //////////////////////////////////////// 172 173 if (!$('.roomview-close').length) { 174 var close_html = '<div class="roomview-close"><a href="#" role="button">Close</a></div>'; 175 $('body').append(close_html); 176 $('.roomview-close').click(function(e) { 177 e.preventDefault(); 178 instance.close_roomview(); 179 }); 180 } 181 182 }, 183 184 inject_room: function(instance, $roomview_element) { 185 var room_html = instance.return_room_html(instance) 186 if (!$roomview_element.hasClass('roomview-initialised')) { 187 //$('body').append(room_html); 188 $roomview_element.after(room_html); 189 $roomview_element.addClass('roomview-initialised'); 190 } 191 }, 192 193 button: function(instance, $roomview_element) { 194 var button_rel = $roomview_element.attr('data-roomview-id'); 195 var $button = $('.roomview-button[data-roomview-id='+button_rel+']'); 196 197 $button.click(function() { 198 if (instance.settings.verbose_mode == true){ 199 } 200 instance.open({ 201 furniture_type: $(this).attr('data-roomview-furniture-type') && typeof $(this).attr('data-roomview-furniture-type') != 'undefined' ? $(this).attr('data-roomview-furniture-type') : '', 202 wall_type: $(this).attr('data-roomview-wall-type') && typeof $(this).attr('data-roomview-wall-type') != 'undefined' ? $(this).attr('data-roomview-wall-type') : '' 203 }); 204 }); 205 }, 206 207 open: function(options) { 208 var instance = this; 209 var $roomview_element = $(this.element); 210 var $roomview_room = $('[data-roomview-element-id="' + $roomview_element.attr('data-roomview-id') + '"]'); 211 212 var button_rel = $(instance).attr('data-roomview-id'); 213 214 // Reset scene 215 $roomview_room.find('.wall').attr('class', '').addClass('wall wall-type-' + instance.settings.wall_type); 216 $roomview_room.find('.floor').attr('class', '').addClass('floor floor-type-' + instance.settings.floor_type); 217 $roomview_room.find('.roomview-object').addClass('roomview-object-hidden'); 218 $roomview_room.find('.roomview-object.furniture-type-' + instance.settings.furniture_type + '').removeClass('roomview-object-hidden'); 219 instance.settings.furniture_settings = instance.settings.furniture_items[instance.settings.furniture_type]; 220 var furniture_settings_for_scale = instance.settings.furniture_items[instance.settings.furniture_type]; 221 222 // Set custom scene attributes if supplied 223 if (options && typeof options != 'undefined') { 224 if (options.wall_type && options.wall_type != '') { 225 $roomview_room.find('.wall').attr('class', '').addClass('wall wall-type-' + options.wall_type); 226 } 227 if (options.floor_type && options.floor_type != '') { 228 $roomview_room.find('.floor').attr('class', '').addClass('floor floor-type-' + options.floor_type); 229 } 230 if (options.furniture_type && options.furniture_type != '') { 231 $roomview_room.find('.roomview-object').addClass('roomview-object-hidden'); 232 $roomview_room.find('.roomview-object.furniture-type-' + options.furniture_type + '').removeClass('roomview-object-hidden'); 233 instance.settings.furniture_settings = instance.settings.furniture_items[options.furniture_type]; 234 235 var furniture_settings_for_scale = instance.settings.furniture_items[options.furniture_type]; 236 } 237 } 238 239 instance.scale_placeholder_artwork(instance, $roomview_element, furniture_settings_for_scale); 240 241 instance.settings.before_open(button_rel, $(this)); 242 $('body').addClass('roomview-active'); 243 $('.draginner').css({'transform': 'none', 'transition': 'none'}); 244 $roomview_element.addClass('roomview-active-element'); 245 instance.scale_artwork(instance, $roomview_element, $roomview_room); 246 $roomview_room.css('opacity',1).addClass('roomview-active'); 247 try { 248 h.accessibility.on_popup_opening('.roomview-close', '.roomview-close a', '.roomview-close'); 249 } 250 catch(error) { 251 console.error(error); 252 } 253 }, 254 255 return_room_html: function(instance) { 256 257 if (instance.settings.custom_room_html) { 258 259 var room_html = instance.settings.custom_room_html; 260 261 } else { 262 var room_html = '<div data-roomview-element-id="' + $(instance.element).attr('data-roomview-id') + '" class="room-wrapper">'; 263 room_html += '<div class="room">'; 264 room_html += '<div class="wall wall-type-'+instance.settings.wall_type+'">'; 265 room_html += '<div class="wall-texture"></div>'; 266 room_html += '<div class="wall-inner">'; 267 268 var value; 269 Object.keys(instance.settings.furniture_items).forEac
269h(function(key) { 270 var furniture_options = instance.settings.furniture_items[key]; 271 var hidden_classname = instance.settings.furniture_settings.id == furniture_options.id ? '' : ' roomview-object-hidden'; 272 room_html += '<div class="roomview-object furniture-type-' + furniture_options.classname_suffix + '' + hidden_classname + '" data-object-cm-width="' + furniture_options.furniture_width_cm + '" data-object-name="' + furniture_options.id + '"></div>'; 273 }); 274 275 room_html += '</div>'; 276 room_html += '</div>'; 277 room_html += '<div class="floor floor-type-'+instance.settings.floor_type+'"></div>'; 278 room_html += '</div>'; 279 room_html += '</div>'; 280 281 } 282 return room_html; 283 }, 284 285 close_roomview: function() { 286 // Not instance-based for the moment... close ALL instances 287 $('body').removeClass('roomview-active roomview-artwork-switched'); 288 console.log('addClass room-css-transitions'); 289 $('.roomview-image.roomview-active-element').addClass('room-css-transitions'); 290 $('.roomview-image.roomview-active-element').removeClass('roomview-active-element').css('transform','translateY(0) scale(1)'); 291 $('.draginner').css({'transform': '', 'transition': ''}); 292 $('.room-wrapper').css('opacity',0).removeClass('roomview-active'); 293 try { 294 h.accessibility.on_popup_closing(); 295 } 296 catch(error) { 297 console.error(error); 298 } 299 setTimeout(function() { 300 $('.roomview-image').removeClass('roomview-artwork-scaled'); 301 }, 600); 302 }, 303 304 create_placeholder_artwork: function(instance, $roomview_element) { 305 306 var $roomview_room = $('[data-roomview-element-id="' + $roomview_element.attr('data-roomview-id') + '"]'); 307 308 if (!$roomview_room.find('.wall').find('.placeholder-artwork').length ){ 309 var $wall = $roomview_room.find('.wall-inner'); 310 $roomview_element.clone().removeClass('roomview-image').addClass('placeholder-artwork').appendTo($wall); 311 } 312 313 instance.scale_placeholder_artwork(instance, $roomview_element); 314 }, 315 316 scale_placeholder_artwork: function(instance, $roomview_element, furniture_settings) { 317 318 // SCALE DUMMY ARTWORK 319 var $roomview_room = $('[data-roomview-element-id="' + $roomview_element.attr('data-roomview-id') + '"]'); 320 321 // Create a scale ratio 322 var object_px = $roomview_room.find('.roomview-object:not(.roomview-object-hidden)').width(); 323 var object_width_cm = $roomview_room.find('.roomview-object:not(.roomview-object-hidden)').attr('data-object-cm-width'); 324 325 326 // console.log(furniture_settings); 327 if (typeof furniture_settings != undefined && furniture_settings) { 328 329 if (typeof furniture_settings.furniture_width_cm != undefined && furniture_settings.furniture_width_cm){ 330 object_width_cm = furniture_settings.furniture_width_cm 331 } 332 if (typeof furniture_settings.classname_suffix != undefined && furniture_settings.classname_suffix){ 333 var suffix = furniture_settings.classname_suffix; 334 object_px = $('.roomview-object.furniture-type-'+suffix).width(); 335 } 336 } 337 338 // Work out px size of scaled artwork 339 var artwork_width_cm = $roomview_element.attr('data-roomview-artwork-cm-width'); 340 341 342 var artwork_scale = object_px / object_width_cm; 343 var dummy_artwork_px = artwork_width_cm * artwork_scale; 344 345 // Apply size 346 $roomview_room.find('.placeholder-artwork').width(dummy_artwork_px); 347 348 // Set hanging height 349 var eyeline_height = instance.settings.hanging_height_cm; // add data-attribute override 350 var eyeline_height = eyeline_height * artwork_scale; 351 var bottom = eyeline_height - ( $roomview_room.find('.placeholder-artwork').height() * (1 - instance.settings.hanging_ratio)); 352 353 var minimum_artwork_bottom_value = (instance.settings.visual_mode == 'photo' ? 20 : 80) + (instance.settings.furniture_settings.artwork_minimum_floor_clearance && typeof instance.settings.furniture_settings.artwork_minimum_floor_clearance != 'undefined' ? instance.settings.furniture_settings.artwork_minimum_floor_clearance : 0); 354 355 if (bottom < minimum_artwork_bottom_value) { 356 var bottom = minimum_artwork_bottom_value; 357 } 358 359 // Adjust positioning of artwork to centre of eyeline 360 $roomview_room.find('.placeholder-artwork').css({ 361 'bottom' : bottom 362 }); 363 364 // Scale the wrapper if the image doesnt fit in the viewport 365 instance.scale_wrapper(instance, $roomview_element, $roomview_room); 366 367 }, 368 369 scale_wrapper: function(instance, $roomview_element, $roomview_room) { 370 371 372 // Scale if top of artwork is being cut off 373 374 var $wall_texture = $roomview_room.find('.wall-texture'); 375 var $floor = $roomview_room.find('.floor'); 376 377 // Reset transform before we start 378 $roomview_room.css('transform',''); 379 $wall_texture.attr('style',''); 380 $floor.attr('style',''); 381 382 var scaled_artwork_top_target = $roomview_room.find('.placeholder-artwork')[0].getBoundingClientRect().top; 383 var scaled_artwork_left_target = $roomview_room.find('.placeholder-artwork')[0].getBoundingClientRect().left; 384 385 function runScale(new_scene_scale_ratio) { 386 $roomview_room.css('transform', 'scale(' + new_scene_scale_ratio + ')'); 387
388 //////////////////////////////////////////////// 389 // ENSURE THAT WALL ALWAYS FILLS THE SCREEN 390 //////////////////////////////////////////////// 391 var wall_texture_bounds = $wall_texture[0].getBoundingClientRect(); 392 var wall_unscaled_px_height = $wall_texture.height(); 393 var wall_unscaled_px_width = $wall_texture.width(); 394 395 /// HEIGHT 396 var scaled_wall_bottom = wall_texture_bounds.bottom; ///TARGET AREA TO COVER 397 var scaled_wall_height = wall_texture_bounds.height; 398 var height_scale_ratio = scaled_wall_bottom / scaled_wall_height; 399 var new_unscaled_px_height = wall_unscaled_px_height * height_scale_ratio; 400 401 /// WIDTH 402 var scaled_wall_width= wall_texture_bounds.width; ///TARGET AREA TO COVER 403 var width_scale_ratio = $(window).width() / scaled_wall_width; 404 var new_unscaled_px_width = wall_unscaled_px_width * width_scale_ratio; 405 406 $wall_texture.height(new_unscaled_px_height).width(new_unscaled_px_width); 407 $floor.width(new_unscaled_px_width); 408 } 409 410 function scaleHeight() { 411 412 var amount_off_screen = scaled_artwork_top_target; 413 var viewport_height = $(window).height(); 414 415 var new_target_viewport_height = viewport_height - (amount_off_screen) + (instance.settings.minimum_top_margin); // Removed *2 from both amount_off_screen and minimum_top_margin as we now align to the bottom so it doesnt need to be doubled for top and bottom 416 var new_scene_scale_ratio = viewport_height / new_target_viewport_height; 417 418 runScale(new_scene_scale_ratio); 419 } 420 421 function scaleWidth() { 422 423 var amount_off_screen = scaled_artwork_left_target; 424 var viewport_width = $(window).width(); 425 426 var new_target_viewport_width = viewport_width - (2 * amount_off_screen) + (2 * instance.settings.minimum_left_margin); 427 var new_scene_scale_ratio = viewport_width / new_target_viewport_width; 428 429 runScale(new_scene_scale_ratio); 430 } 431 432 // 1. Check if the height or width is overflowing the screen 433 // 2. If it is overflowing, scale using that axis. 434 // 3. After scaling check if the other axis is overlaping, and if it is scale by that axis instead 435 if (scaled_artwork_top_target < instance.settings.minimum_top_margin) { 436 scaleHeight(); 437 if ($roomview_room.find('.placeholder-artwork')[0].getBoundingClientRect().left < instance.settings.minimum_left_margin) { 438 scaleWidth(); 439 } 440 } else if (scaled_artwork_left_target < instance.settings.minimum_left_margin) { 441 scaleWidth(); 442 if ($roomview_room.find('.placeholder-artwork')[0].getBoundingClientRect().top < instance.settings.minimum_top_margin) { 443 scaleHeight(); 444 } 445 } 446 447 }, 448 449 scale_artwork: function(instance, $roomview_element, $roomview_room) { 450 451 // Scale the wrapper if the image doesnt fit in the viewport 452 instance.scale_wrapper(instance, $roomview_element, $roomview_room); 453 454 if (instance.settings.verbose_mode == true){ 455 console.log('scale_artwork'); 456 } 457 if (!$roomview_element.hasClass('roomview-initialised')){ 458 return 459 } 460 461 var $placeholder_artwork = $roomview_room.find('img.placeholder-artwork'); 462 var placeholder_artwork_bounds = $placeholder_artwork[0].getBoundingClientRect(); 463 var roomview_element_bounds = $roomview_element[0].getBoundingClientRect(); 464 465 466 if ($roomview_element.hasClass('roomview-artwork-scaled')) { 467 468 /// RE-SCALE artwork when it is already scaled 469 470 //if ($roomview_element.hasClass('roomview-artwork-scaled roomview-initialised')){ 471 if (instance.settings.verbose_mode == true){ 472 console.log('Artwork in scale mode - adjust position'); 473 } 474 console.log('removeClass room-css-transitions'); 475 $roomview_element.removeClass('room-css-transitions'); 476 477 // Calculate the Scale 478 var unscaled_artwork_px_height = $roomview_element.height(); 479 var dummy_artwork_px_height = placeholder_artwork_bounds.height; 480 var final_visible_artwork_scale = dummy_artwork_px_height / unscaled_artwork_px_height; 481 482 //Get the current transform 483 var current_transformation = $roomview_element.css('transform'); 484 var transform_values = current_transformation.split('(')[1]; 485 transform_values = transform_values.split(')')[0]; 486 transform_values = transform_values.split(','); 487 488 var current_transformation_Y = transform_values[5]; 489 var current_transformation_X = transform_values[4]; 490 491 //Work out how much distance to transition Y 492 //Work out the difference between the target and the visible 493 var scaled_artwork_top_target = placeholder_artwork_bounds.top; 494 var scaled_artwork_top_current = roomview_element_bounds.top; 495 var scaled_artwork_top_difference = scaled_artwork_top_target - scaled_artwork_top_current; 496 497 var adjustment_distance_Y = parseFloat(current_transformation_Y) + scaled_artwork_top_difference; 498 499 //Work out how much distance to transition X 500 //Work out the difference between the target and the visible 501 var scaled_artwork_left_target = placeholder_artwork_bounds.left; 502 var scaled_artwork_left_current = roomview_element_bounds.left; 503 var scaled_artwork_left_difference = scaled_artwork_left_target - scaled_artwork_left_current; 504 505 var adjustment_distance_X = parseFloat(current_transformation_X) + scaled_artwork_left_difference; 506 507 $roomview_element.addClass('roomview-artwork-scaled').css('transform','translateY('+adjustment_distance_Y+'px) translateX('+adjustment_distance_X+'px) scale('+final_visible_artwork_scale+')'); 508 509 } else { 510 511 512 ///TRANSITION FROM FULL-SIZE ARTWORK TO SCALED 513 514 515 if (instance.settings.verbose_mode == true){ 516 console.log('Scale from full size'); 517 } 518 // Calculate the Scale 519 var unscaled_artwork_px_height = $roomview_element.height(); 520 var dummy_artwork_px_height = placeholder_artwork_bounds.height; 521 var final_visible_artwork_scale = dummy_artwork_px_height / unscaled_artwork_px_height; 522 523 // Get the new centred (/2) Y offset of the visible artwork once scaled 524 var scaled_visible_artwork_offset_Y = ( unscaled_artwork_px_height - dummy_artwork_px_height ) / 2; 525 526 //Work out how much distance to transition Y 527 var scaled_artwork_top_target = placeholder_artwork_bounds.top; 528 var unscaled_artwork_top = roomview_element_bounds.top; 529 var scaled_artwork_top_difference = scaled_artwork_top_target - unscaled_artwork_top; 530 var adjustment_distance_Y = scaled_artwork_top_difference - scaled_visible_artwork_offset_Y; 531 532 533 var unscaled_artwork_px_width = $roomview_element.width(); 534 var dummy_artwork_px_width = placeholder_artwork_bounds.width; 535 536 // Get the new centred (/2) X offset of the visible artwork once scaled 537 var scaled_visible_artwork_offset_X = ( unscaled_artwork_px_width - dummy_artwork_px_width ) / 2; 538 539 //Work out how much distance to transition X 540 var scaled_artwork_left_target = placeholder_artwork_bounds.left; 541 var unscaled_artwork_left = roomview_element_bounds.left; 542 var scaled_artwork_left_difference = scaled_artwork_left_target - unscaled_artwork_left; 543 var adjustment_distance_X = scaled_artwork_left_difference - scaled_visible_artwork_offset_X; 544 545 console.log('addclass room-css-transitions'); 546 $roomview_element.addClass('room-css-transitions'); 547 $roomview_element.addClass('roomview-artwork-scaled').css('transform','translateY('+adjustment_distance_Y+'px) translateX('+adjustment_distance_X+'px) scale('+final_visible_artwork_scale+')'); 548 549 $roomview_room.find('.room').addClass('animate'); 550 551 setTimeout(function() { 552 $roomview_room.find('.room').removeClass('animate'); 553 }, 10, $roomview_room); 554 555 setTimeout(function() { 556 $('body').addClass('roomview-artwork-switched'); 557 }, 1000, $roomview_element); 558 559 } 560 561 } 562 563 }); 564 565 // A really lightweight plugin wrapper around the constructor, 566 // preventing against multiple instantiations 567 $.fn[pluginName] = function ( options ) { 568 return this.each(function () { 569 if (typeof options === "string") { 570 var args = Array.prototype.slice.call(arguments, 1), 571 plugin = $.data(this, 'plugin_' + pluginName);
572 plugin[options].apply(plugin, args); 573 } else if (!$.data(this, 'plugin_' + pluginName)) { 574 $.data(this, 'plugin_' + pluginName, 575 new Plugin( this, options )); 576 } 577 }); 578 }; 579 580 581} )( jQuery, window, document );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.