OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /* | 5 /* |
6 * Base class that Ribbon uses to display photos. | 6 * Base class that Ribbon uses to display photos. |
7 */ | 7 */ |
8 | 8 |
9 function RibbonClient() {} | 9 function RibbonClient() {} |
10 | 10 |
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 this.selectedIndex_ = -1; | 494 this.selectedIndex_ = -1; |
495 | 495 |
496 this.arrowLeft_ = arrowLeft; | 496 this.arrowLeft_ = arrowLeft; |
497 this.arrowLeft_. | 497 this.arrowLeft_. |
498 addEventListener('click', this.selectNext.bind(this, -1, null)); | 498 addEventListener('click', this.selectNext.bind(this, -1, null)); |
499 | 499 |
500 this.arrowRight_ = arrowRight; | 500 this.arrowRight_ = arrowRight; |
501 this.arrowRight_. | 501 this.arrowRight_. |
502 addEventListener('click', this.selectNext.bind(this, 1, null)); | 502 addEventListener('click', this.selectNext.bind(this, 1, null)); |
503 | 503 |
504 this.fadeLeft_ = this.document_.createElement('div'); | 504 this.bar_ = this.document_.createElement('div'); |
505 this.fadeLeft_.className = 'fade left'; | 505 this.bar_.className = 'ribbon'; |
506 this.container_.appendChild(this.fadeLeft_); | 506 this.container_.appendChild(this.bar_); |
507 | |
508 this.bars_ = []; | |
509 for (var i = 0; i < 2; i++) { | |
510 var bar = this.document_.createElement('div'); | |
511 bar.className = 'ribbon'; | |
512 this.container_.appendChild(bar); | |
513 this.bars_.push(bar); | |
514 } | |
515 this.activeBarIndex_ = 0; | |
516 ImageUtil.setAttribute(this.bars_[0], 'inactive', false); | |
517 ImageUtil.setAttribute(this.bars_[1], 'inactive', true); | |
518 | |
519 this.fadeRight_ = this.document_.createElement('div'); | |
520 this.fadeRight_.className = 'fade right'; | |
521 this.container_.appendChild(this.fadeRight_); | |
522 } | 507 } |
523 | 508 |
524 Ribbon.PAGING_SINGLE_ITEM_DELAY = 20; | 509 Ribbon.PAGING_SINGLE_ITEM_DELAY = 20; |
525 Ribbon.PAGING_ANIMATION_DURATION = 200; | 510 Ribbon.PAGING_ANIMATION_DURATION = 200; |
526 | 511 |
527 Ribbon.prototype.getSelectedItem = function () { | 512 Ribbon.prototype.getSelectedItem = function () { |
528 return this.items_[this.selectedIndex_]; | 513 return this.items_[this.selectedIndex_]; |
529 }; | 514 }; |
530 | 515 |
531 Ribbon.prototype.clear = function() { | 516 Ribbon.prototype.clear = function() { |
532 this.bars_[0].textContent = ''; | 517 this.bar_.textContent = ''; |
533 this.bars_[1].textContent = ''; | |
534 this.activeBarIndex_ = 0; | |
535 ImageUtil.setAttribute(this.bars_[0], 'inactive', false); | |
536 ImageUtil.setAttribute(this.bars_[1], 'inactive', true); | |
537 this.items_ = []; | 518 this.items_ = []; |
538 this.selectedIndex_ = -1; | 519 this.selectedIndex_ = -1; |
539 this.firstVisibleIndex_ = 0; | 520 this.firstVisibleIndex_ = 0; |
540 this.lastVisibleIndex_ = -1; // Zero thumbnails | 521 this.lastVisibleIndex_ = -1; // Zero thumbnails |
541 this.sequenceDirection_ = 0; | 522 this.sequenceDirection_ = 0; |
542 this.sequenceLength_ = 0; | 523 this.sequenceLength_ = 0; |
543 }; | 524 }; |
544 | 525 |
545 Ribbon.prototype.add = function(url) { | 526 Ribbon.prototype.add = function(url) { |
546 var index = this.items_.length; | 527 var index = this.items_.length; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 | 613 |
633 var selectedItem = this.getSelectedItem(); | 614 var selectedItem = this.getSelectedItem(); |
634 var self = this; | 615 var self = this; |
635 var item = this.items_[index]; | 616 var item = this.items_[index]; |
636 item.fetchMetadata(this.metadataProvider_, function(metadata) { | 617 item.fetchMetadata(this.metadataProvider_, function(metadata) { |
637 if (!selectedItem.isSelected()) return; | 618 if (!selectedItem.isSelected()) return; |
638 self.client_.prefetchImage(index, item.getContent(), metadata); | 619 self.client_.prefetchImage(index, item.getContent(), metadata); |
639 }); | 620 }); |
640 }; | 621 }; |
641 | 622 |
642 Ribbon.prototype.updateControls_ = function() { | 623 Ribbon.ITEMS_COUNT = 5; |
643 ImageUtil.setAttribute(this.fadeLeft_, 'active', this.firstVisibleIndex_ > 0); | |
644 ImageUtil.setAttribute(this.fadeRight_, 'active', | |
645 this.lastVisibleIndex_ + 1 < this.items_.length); | |
646 }; | |
647 | 624 |
648 Ribbon.prototype.redraw = function() { | 625 Ribbon.prototype.redraw = function() { |
649 // The thumbnails are square. | 626 // TODO(dgozman): use margin instead of 2 here. |
650 var itemWidth = this.bars_[0].parentNode.clientHeight; | 627 var itemWidth = this.bar_.clientHeight - 2; |
651 var width = this.bars_[0].parentNode.clientWidth; | 628 var fullItems = Ribbon.ITEMS_COUNT; |
652 | 629 fullItems = Math.min(fullItems, this.items_.length); |
653 var fullItems = Math.floor(width / itemWidth); | 630 var right = Math.floor((fullItems - 1) / 2); |
654 | 631 |
655 var fullWidth = fullItems * itemWidth; | 632 var fullWidth = fullItems * itemWidth; |
| 633 this.bar_.style.width = fullWidth + 'px'; |
656 | 634 |
657 this.bars_[0].style.width = fullWidth + 'px'; | 635 var lastIndex = this.selectedIndex_ + right; |
658 this.bars_[1].style.width = fullWidth + 'px'; | 636 lastIndex = Math.max(lastIndex, fullItems - 1); |
659 | 637 lastIndex = Math.min(lastIndex, this.items_.length - 1); |
660 // Position the shadows over the first and the last visible thumbnails. | 638 var firstIndex = lastIndex - fullItems + 1; |
661 this.fadeLeft_.style.left = 0; | |
662 this.fadeRight_.style.right = (width - fullWidth) + 'px'; | |
663 | |
664 fullItems = Math.min(fullItems, this.items_.length); | |
665 var firstIndex = this.firstVisibleIndex_; | |
666 var lastIndex = firstIndex + fullItems - 1; | |
667 | |
668 if (this.selectedIndex_ <= firstIndex && firstIndex > 0) { | |
669 firstIndex = Math.max(0, this.selectedIndex_ - (fullItems >> 1)); | |
670 lastIndex = firstIndex + fullItems - 1; | |
671 } | |
672 | |
673 if (this.selectedIndex_ >= lastIndex && lastIndex < this.items_.length - 1) { | |
674 lastIndex = Math.min(this.items_.length - 1, | |
675 this.selectedIndex_ + (fullItems >> 1)); | |
676 firstIndex = lastIndex - fullItems + 1; | |
677 } | |
678 | |
679 this.updateControls_(); | |
680 | 639 |
681 if (this.firstVisibleIndex_ == firstIndex && | 640 if (this.firstVisibleIndex_ == firstIndex && |
682 this.lastVisibleIndex_ == lastIndex) { | 641 this.lastVisibleIndex_ == lastIndex) { |
683 return; | 642 return; |
684 } | 643 } |
685 | 644 |
686 var activeBar = this.bars_[this.activeBarIndex_]; | 645 if (this.lastVisibleIndex_ == -1) { |
687 var children = activeBar.childNodes; | 646 this.firstVisibleIndex_ = firstIndex; |
688 var totalDuration = children.length * Ribbon.PAGING_SINGLE_ITEM_DELAY + | 647 this.lastVisibleIndex_ = lastIndex; |
689 Ribbon.PAGING_ANIMATION_DURATION; | |
690 | |
691 var direction = 1; | |
692 var delay = 0; | |
693 if (firstIndex < this.firstVisibleIndex_) { | |
694 direction = -1; | |
695 delay = (children.length - 1) * Ribbon.PAGING_SINGLE_ITEM_DELAY; | |
696 } | |
697 for (var index = 0; index < children.length; ++index) { | |
698 setTimeout( | |
699 ImageUtil.setAttribute.bind(null, children[index], 'inactive', true), | |
700 delay); | |
701 delay += direction * Ribbon.PAGING_SINGLE_ITEM_DELAY; | |
702 } | 648 } |
703 | 649 |
704 // Place inactive bar below active after animation is finished. | 650 this.bar_.textContent = ''; |
705 setTimeout( | 651 var startIndex = Math.min(firstIndex, this.firstVisibleIndex_); |
706 ImageUtil.setAttribute.bind(null, activeBar, 'inactive', true), | 652 var toRemove = []; |
707 totalDuration); | 653 for (var index = startIndex + 1; |
| 654 index <= Math.max(lastIndex, this.lastVisibleIndex_); |
| 655 ++index) { |
| 656 var box = this.items_[index].getBox(0); |
| 657 box.style.marginLeft = '0'; |
| 658 this.bar_.appendChild(box); |
| 659 if (index < firstIndex || index > lastIndex) { |
| 660 toRemove.push(index); |
| 661 } |
| 662 } |
| 663 |
| 664 var margin = itemWidth * Math.abs(firstIndex - this.firstVisibleIndex_); |
| 665 var startBox = this.items_[startIndex].getBox(0); |
| 666 if (startIndex == firstIndex) { |
| 667 startBox.style.marginLeft = -margin + 'px'; |
| 668 if (this.bar_.firstChild) |
| 669 this.bar_.insertBefore(startBox, this.bar_.firstChild); |
| 670 else |
| 671 this.bar_.appendChild(startBox); |
| 672 setTimeout(function() { |
| 673 startBox.style.marginLeft = '0'; |
| 674 }, 0); |
| 675 } else { |
| 676 toRemove.push(startBox); |
| 677 startBox.style.marginLeft = '0'; |
| 678 if (this.bar_.firstChild) |
| 679 this.bar_.insertBefore(startBox, this.bar_.firstChild); |
| 680 else |
| 681 this.bar_.appendChild(startBox); |
| 682 setTimeout(function() { |
| 683 startBox.style.marginLeft = -margin + 'px'; |
| 684 }, 0); |
| 685 } |
| 686 |
| 687 if (firstIndex > 0 && this.selectedIndex_ != firstIndex) { |
| 688 this.bar_.classList.add('fade-left'); |
| 689 } else { |
| 690 this.bar_.classList.remove('fade-left'); |
| 691 } |
| 692 |
| 693 if (lastIndex < this.items_.length - 1 && this.selectedIndex_ != lastIndex) { |
| 694 this.bar_.classList.add('fade-right'); |
| 695 } else { |
| 696 this.bar_.classList.remove('fade-right'); |
| 697 } |
708 | 698 |
709 this.firstVisibleIndex_ = firstIndex; | 699 this.firstVisibleIndex_ = firstIndex; |
710 this.lastVisibleIndex_ = lastIndex; | 700 this.lastVisibleIndex_ = lastIndex; |
711 | 701 |
712 this.activeBarIndex_ = 1 - this.activeBarIndex_; | 702 var self = this; |
713 activeBar = this.bars_[this.activeBarIndex_]; | 703 setTimeout(function() { |
714 activeBar.textContent = ''; | 704 for (var i = 0; i < toRemove.length; i++) { |
715 for (var index = firstIndex; index <= lastIndex; ++index) { | 705 var index = toRemove[i]; |
716 var box = this.items_[index].getBox(this.activeBarIndex_); | 706 if (i < this.firstVisibleIndex_ || i > this.lastVisibleIndex_) { |
717 ImageUtil.setAttribute(box, 'inactive', false); | 707 var box = this.items_[index].getBox(0); |
718 activeBar.appendChild(box); | 708 if (box.parentNode == this.bar_) |
719 } | 709 this.bar_.removeChild(box); |
720 | 710 } |
721 // Place active bar above inactive after animation is finished. | 711 } |
722 setTimeout( | 712 }, 200); |
723 ImageUtil.setAttribute.bind(null, activeBar, 'inactive', false), | |
724 totalDuration); | |
725 }; | 713 }; |
726 | 714 |
727 Ribbon.prototype.getNextSelectedIndex_ = function(direction) { | 715 Ribbon.prototype.getNextSelectedIndex_ = function(direction) { |
728 var index = this.selectedIndex_ + (direction > 0 ? 1 : -1); | 716 var index = this.selectedIndex_ + (direction > 0 ? 1 : -1); |
729 if (index == -1) return this.items_.length - 1; | 717 if (index == -1) return this.items_.length - 1; |
730 if (index == this.items_.length) return 0; | 718 if (index == this.items_.length) return 0; |
731 return index; | 719 return index; |
732 }; | 720 }; |
733 | 721 |
734 Ribbon.prototype.selectNext = function(direction, opt_callback) { | 722 Ribbon.prototype.selectNext = function(direction, opt_callback) { |
(...skipping 23 matching lines...) Expand all Loading... |
758 function() { self.slideShowTimeout_ = setTimeout(nextSlide, 5000) }); | 746 function() { self.slideShowTimeout_ = setTimeout(nextSlide, 5000) }); |
759 } | 747 } |
760 nextSlide(); | 748 nextSlide(); |
761 } | 749 } |
762 }; | 750 }; |
763 | 751 |
764 Ribbon.Item = function(index, url, document, selectClosure) { | 752 Ribbon.Item = function(index, url, document, selectClosure) { |
765 this.index_ = index; | 753 this.index_ = index; |
766 this.url_ = url; | 754 this.url_ = url; |
767 | 755 |
768 this.boxes_ = []; | 756 this.box_ = document.createElement('div'); |
769 this.wrappers_ = []; | 757 this.box_.className = 'ribbon-image'; |
770 this.imgs_ = []; | 758 this.box_.addEventListener('click', selectClosure); |
771 | 759 |
772 for (var i = 0; i < 2; i++) { | 760 this.wrapper_ = document.createElement('div'); |
773 var box = document.createElement('div'); | 761 this.wrapper_.className = 'image-wrapper'; |
774 box.className = 'ribbon-image'; | 762 this.box_.appendChild(this.wrapper_); |
775 box.addEventListener('click', selectClosure); | |
776 | 763 |
777 var wrapper = document.createElement('div'); | 764 this.img_ = document.createElement('img'); |
778 wrapper.className = 'image-wrapper'; | 765 this.wrapper_.appendChild(this.img_); |
779 box.appendChild(wrapper); | |
780 | |
781 var img = document.createElement('img'); | |
782 wrapper.appendChild(img); | |
783 | |
784 this.boxes_.push(box); | |
785 this.wrappers_.push(wrapper); | |
786 this.imgs_.push(img); | |
787 } | |
788 | 766 |
789 this.original_ = true; | 767 this.original_ = true; |
790 this.copyName_ = null; | 768 this.copyName_ = null; |
791 }; | 769 }; |
792 | 770 |
793 Ribbon.Item.prototype.getIndex = function () { return this.index_ }; | 771 Ribbon.Item.prototype.getIndex = function () { return this.index_ }; |
794 | 772 |
795 Ribbon.Item.prototype.getBox = function (index) { return this.boxes_[index] }; | 773 Ribbon.Item.prototype.getBox = function () { return this.box_ }; |
796 | 774 |
797 Ribbon.Item.prototype.isOriginal = function () { return this.original_ }; | 775 Ribbon.Item.prototype.isOriginal = function () { return this.original_ }; |
798 | 776 |
799 Ribbon.Item.prototype.getUrl = function () { return this.url_ }; | 777 Ribbon.Item.prototype.getUrl = function () { return this.url_ }; |
800 Ribbon.Item.prototype.setUrl = function (url) { this.url_ = url }; | 778 Ribbon.Item.prototype.setUrl = function (url) { this.url_ = url }; |
801 | 779 |
802 Ribbon.Item.prototype.getCopyName = function () { return this.copyName_ }; | 780 Ribbon.Item.prototype.getCopyName = function () { return this.copyName_ }; |
803 | 781 |
804 Ribbon.Item.prototype.isSelected = function() { | 782 Ribbon.Item.prototype.isSelected = function() { |
805 return this.boxes_[0].hasAttribute('selected'); | 783 return this.box_.hasAttribute('selected'); |
806 }; | 784 }; |
807 | 785 |
808 Ribbon.Item.prototype.select = function(on) { | 786 Ribbon.Item.prototype.select = function(on) { |
809 for (var i = 0; i < 2; i++) { | 787 ImageUtil.setAttribute(this.box_, 'selected', on); |
810 ImageUtil.setAttribute(this.boxes_[i], 'selected', on); | |
811 } | |
812 }; | 788 }; |
813 | 789 |
814 Ribbon.Item.prototype.updateThumbnail = function(canvas) { | 790 Ribbon.Item.prototype.updateThumbnail = function(canvas) { |
815 if (this.canvas_) | 791 if (this.canvas_) |
816 return; // The image is being saved, the thumbnail is already up-to-date. | 792 return; // The image is being saved, the thumbnail is already up-to-date. |
817 | 793 |
818 var metadataEncoder = | 794 var metadataEncoder = |
819 ImageEncoder.encodeMetadata(this.getMetadata(), canvas, 1); | 795 ImageEncoder.encodeMetadata(this.getMetadata(), canvas, 1); |
820 this.setMetadata(metadataEncoder.getMetadata()); | 796 this.setMetadata(metadataEncoder.getMetadata()); |
821 }; | 797 }; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 img.style.marginTop = percent((1 - aspect) / 2); | 988 img.style.marginTop = percent((1 - aspect) / 2); |
1013 img.style.marginLeft = 0; | 989 img.style.marginLeft = 0; |
1014 } | 990 } |
1015 } | 991 } |
1016 | 992 |
1017 var webkitTransform = transform ? | 993 var webkitTransform = transform ? |
1018 ('scaleX(' + transform.scaleX + ') ' + | 994 ('scaleX(' + transform.scaleX + ') ' + |
1019 'scaleY(' + transform.scaleY + ') ' + | 995 'scaleY(' + transform.scaleY + ') ' + |
1020 'rotate(' + transform.rotate90 * 90 + 'deg)') : | 996 'rotate(' + transform.rotate90 * 90 + 'deg)') : |
1021 ''; | 997 ''; |
| 998 this.wrapper_.style.webkitTransform = webkitTransform; |
1022 | 999 |
1023 for (var i = 0; i < 2; i++) { | 1000 var img = this.img_; |
1024 this.wrappers_[i].style.webkitTransform = webkitTransform; | |
1025 | 1001 |
1026 var img = this.imgs_[i]; | 1002 if (metadata.width && metadata.height) { |
| 1003 var aspect = metadata.width / metadata.height; |
| 1004 if (transform && transform.rotate90) { |
| 1005 aspect = 1 / aspect; |
| 1006 } |
| 1007 resizeToFill(img, aspect); |
| 1008 } else { |
| 1009 // No metadata available, loading the thumbnail first, |
| 1010 // then adjust the size. |
| 1011 img.style.maxWidth = '100%'; |
| 1012 img.style.maxHeight = '100%'; |
1027 | 1013 |
1028 if (metadata.width && metadata.height) { | 1014 function onLoad(image) { |
1029 var aspect = metadata.width / metadata.height; | 1015 image.style.maxWidth = ''; |
1030 if (transform && transform.rotate90) { | 1016 image.style.maxHeight = ''; |
1031 aspect = 1 / aspect; | 1017 resizeToFill(image, image.width / image.height); |
1032 } | 1018 } |
1033 resizeToFill(img, aspect); | 1019 img.onload = onLoad.bind(null, img); |
1034 } else { | 1020 } |
1035 // No metadata available, loading the thumbnail first, | |
1036 // then adjust the size. | |
1037 img.style.maxWidth = '100%'; | |
1038 img.style.maxHeight = '100%'; | |
1039 | 1021 |
1040 function onLoad(image) { | 1022 img.setAttribute('src', url); |
1041 image.style.maxWidth = ''; | |
1042 image.style.maxHeight = ''; | |
1043 resizeToFill(image, image.width / image.height); | |
1044 } | |
1045 img.onload = onLoad.bind(null, img); | |
1046 } | |
1047 | |
1048 img.setAttribute('src', url); | |
1049 } | |
1050 }; | 1023 }; |
1051 | 1024 |
1052 function ShareMode(editor, container, toolbar, shareActions, | 1025 function ShareMode(editor, container, toolbar, shareActions, |
1053 onClick, actionCallback, displayStringFunction) { | 1026 onClick, actionCallback, displayStringFunction) { |
1054 ImageEditor.Mode.call(this, 'share'); | 1027 ImageEditor.Mode.call(this, 'share'); |
1055 | 1028 |
1056 this.message_ = null; | 1029 this.message_ = null; |
1057 | 1030 |
1058 var doc = container.ownerDocument; | 1031 var doc = container.ownerDocument; |
1059 var button = doc.createElement('div'); | 1032 var button = doc.createElement('div'); |
(...skipping 28 matching lines...) Expand all Loading... |
1088 ShareMode.prototype.setUp = function() { | 1061 ShareMode.prototype.setUp = function() { |
1089 ImageEditor.Mode.prototype.setUp.apply(this, arguments); | 1062 ImageEditor.Mode.prototype.setUp.apply(this, arguments); |
1090 ImageUtil.setAttribute(this.menu_, 'hidden', false); | 1063 ImageUtil.setAttribute(this.menu_, 'hidden', false); |
1091 ImageUtil.setAttribute(this.button_, 'pressed', false); | 1064 ImageUtil.setAttribute(this.button_, 'pressed', false); |
1092 }; | 1065 }; |
1093 | 1066 |
1094 ShareMode.prototype.cleanUpUI = function() { | 1067 ShareMode.prototype.cleanUpUI = function() { |
1095 ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments); | 1068 ImageEditor.Mode.prototype.cleanUpUI.apply(this, arguments); |
1096 ImageUtil.setAttribute(this.menu_, 'hidden', true); | 1069 ImageUtil.setAttribute(this.menu_, 'hidden', true); |
1097 }; | 1070 }; |
OLD | NEW |