blob: 7c312e08045ab1a572479ff6d6cb26fda9be9880 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.m.js';
import {beforeNextRender, html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
const colors = [
// row 1
{name: 'annotationColorBlack', color: '#000000'},
{name: 'annotationColorRed', color: '#ff5252'},
{name: 'annotationColorYellow', color: '#ffbc00'},
{name: 'annotationColorGreen', color: '#00c853'},
{name: 'annotationColorCyan', color: '#00b0ff'},
{name: 'annotationColorPurple', color: '#d500f9'},
{name: 'annotationColorBrown', color: '#8d6e63'},
// row 2
{name: 'annotationColorWhite', color: '#fafafa', outline: true},
{name: 'annotationColorCrimson', color: '#a52714'},
{name: 'annotationColorAmber', color: '#ee8100'},
{name: 'annotationColorAvocadoGreen', color: '#558b2f'},
{name: 'annotationColorCobaltBlue', color: '#01579b'},
{name: 'annotationColorDeepPurple', color: '#8e24aa'},
{name: 'annotationColorDarkBrown', color: '#4e342e'},
// row 3
{name: 'annotationColorDarkGrey', color: '#90a4ae'},
{name: 'annotationColorHotPink', color: '#ff4081'},
{name: 'annotationColorOrange', color: '#ff6e40'},
{name: 'annotationColorLime', color: '#aeea00'},
{name: 'annotationColorBlue', color: '#304ffe'},
{name: 'annotationColorViolet', color: '#7c4dff'},
{name: 'annotationColorTeal', color: '#1de9b6'},
// row 4
{name: 'annotationColorLightGrey', color: '#cfd8dc'},
{name: 'annotationColorLightPink', color: '#f8bbd0'},
{name: 'annotationColorLightOrange', color: '#ffccbc'},
{name: 'annotationColorLightGreen', color: '#f0f4c3'},
{name: 'annotationColorLightBlue', color: '#9fa8da'},
{name: 'annotationColorLavender', color: '#d1c4e9'},
{name: 'annotationColorLightTeal', color: '#b2dfdb'},
];
const sizes = [
{name: 'annotationSize1', size: 0},
{name: 'annotationSize2', size: 0.1429},
{name: 'annotationSize3', size: 0.2857},
{name: 'annotationSize4', size: 0.4286},
{name: 'annotationSize8', size: 0.5714},
{name: 'annotationSize12', size: 0.7143},
{name: 'annotationSize16', size: 0.8571},
{name: 'annotationSize20', size: 1},
];
// Displays a set of radio buttons to select from a predefined list of colors
// and sizes.
class ViewerPenOptionsElement extends PolymerElement {
static get is() {
return 'viewer-pen-options';
}
static get template() {
return html`{__html_template__}`;
}
static get properties() {
return {
/** @private */
expanded_: {
type: Boolean,
value: false,
},
selectedSize: {
type: Number,
value: 0.250,
notify: true,
},
selectedColor: {
type: String,
value: '#000000',
notify: true,
},
/** @private */
sizes_: {
type: Array,
value: sizes,
},
/** @private */
colors_: {
type: Array,
value: colors,
},
strings: Object,
};
}
constructor() {
super();
/** @private {Array<!Animation>} */
this.expandAnimations_ = null;
}
/**
* @param {!Event} e
* @private
*/
sizeChanged_(e) {
this.selectedSize = Number(e.target.value);
}
/**
* @param {!Event} e
* @private
*/
colorChanged_(e) {
this.selectedColor = e.target.value;
}
/** @private */
toggleExpanded_() {
this.expanded_ = !this.expanded_;
this.updateExpandedState_();
}
/** @private */
updateExpandedStateAndFinishAnimations_() {
this.updateExpandedState_();
for (const animation of /** @type {!Array<!Animation>} */ (
this.expandAnimations_)) {
animation.finish();
}
}
/** @override */
connectedCallback() {
super.connectedCallback();
beforeNextRender(this, () => {
this.updateExpandedStateAndFinishAnimations_();
});
}
/**
* Updates the state of the UI to reflect the current value of `expanded`.
* Starts or reverses animations and enables/disable controls.
* @private
*/
updateExpandedState_() {
const colors = this.$.colors;
if (!this.expandAnimations_) {
const separator = this.$.separator;
const expand = this.$.expand;
this.expandAnimations_ = [
colors.animate(
[
{height: '32px'},
{height: '188px'},
],
{
easing: 'ease-in-out',
duration: 250,
fill: 'both',
}),
separator.animate(
[
{opacity: 0},
{opacity: 1},
],
{
easing: 'ease-in-out',
duration: 250,
fill: 'both',
}),
expand.animate(
[
{transform: 'rotate(0deg)'},
{transform: 'rotate(180deg)'},
],
{
easing: 'ease-in-out',
duration: 250,
fill: 'forwards',
}),
];
}
for (const animation of this.expandAnimations_) {
// TODO(dstockwell): Ideally we would just set playbackRate,
// but there appears to be a web-animations bug that
// results in the animation getting stuck in the 'pending'
// state sometimes. See crbug.com/938857
const currentTime = animation.currentTime;
animation.cancel();
animation.playbackRate = this.expanded_ ? 1 : -1;
animation.currentTime = currentTime;
animation.play();
}
for (const input of colors.querySelectorAll('input:nth-child(n+8)')) {
input.toggleAttribute('disabled', !this.expanded_);
}
}
/**
* Used to determine equality in computed bindings.
* @param {*} a
* @param {*} b
* @return {boolean} Whether a === b
* @private
*/
equal_(a, b) {
return a === b;
}
/**
* Used to lookup a string in a computed binding.
* @param {Object} strings
* @param {string} name
* @return {string}
* @private
*/
lookup_(strings, name) {
return strings ? strings[name] : '';
}
/**
* Used to remove focus when clicking or tapping on a styled input
* element. This is a workaround until we can use the :focus-visible
* pseudo selector.
* @param {!Event} e
*/
blurOnPointerDown(e) {
const target = e.target;
setTimeout(() => target.blur(), 0);
}
}
customElements.define(ViewerPenOptionsElement.is, ViewerPenOptionsElement);