@google/model-viewer
Version:
Easily display interactive 3D models on the web and in AR!
183 lines (172 loc) • 5.5 kB
JavaScript
/*
* Copyright 2018 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { html, LitElement, property } from 'lit-element';
const PIXEL_SIZE = 10;
export class MagnifyingGlass extends LitElement {
constructor() {
super(...arguments);
this.imageAccessor = null;
this.pixel = null;
this.direction = 'vertical';
this.position = { x: 0, y: 0 };
this.context = null;
this.xRay = true;
this.reticleSize = 1;
}
enhance() {
if (this.pixel == null || this.imageAccessor == null) {
return;
}
this.classList.remove('hidden');
if (this.context == null) {
const canvas = this.shadowRoot.querySelector('canvas');
if (canvas == null) {
return;
}
this.context = canvas.getContext('2d');
}
const { context } = this;
const rect = this.getBoundingClientRect();
const scale = rect.width / this.imageAccessor.width;
for (let y = 0; y < 24; ++y) {
for (let x = 0; x < 24; ++x) {
context.fillStyle = this.imageAccessor.cssColorAt(this.pixel.x + x - 12, this.pixel.y + y - 12);
context.fillRect(x * PIXEL_SIZE, y * PIXEL_SIZE, PIXEL_SIZE, PIXEL_SIZE);
}
}
this.reticleSize = Math.round(26 * scale);
this.position = {
x: this.pixel.x * scale - 130,
y: this.pixel.y * scale - 130
};
}
toggleXRay() {
this.xRay = !this.xRay;
}
hide() {
this.classList.add('hidden');
}
get glassPosition() {
const { width, height } = this.imageAccessor != null ? this.imageAccessor : { width: 0, height: 0 };
const { x, y } = this.pixel != null ? this.pixel : { x: 0, y: 0 };
return this.direction === 'horizontal' ?
x < (width / 2) ? 'right' : 'left' :
y < (height / 2) ? 'bottom' : 'top';
}
render() {
this.enhance();
return html `
<style>
:host {
display: block;
position: relative;
}
#glass {
display: block;
position: absolute;
box-sizing: border-box;
top: 0;
left: 0;
width: 260px;
height: 260px;
transition: transform 0.1s;
z-index: 1;
background-color: transparent;
}
canvas {
box-sizing: border-box;
box-shadow: 0 2px 10px rgba(40, 40, 40, 0.25);
width: 100%;
height: 100%;
transition: opacity 0.3s, transform 0.5s;
opacity: 1;
}
#glass.top canvas {
transform: translate(0, -180px);
}
#glass.bottom canvas {
transform: translate(0, 180px);
}
#glass.left canvas {
transform: translate(-180px, 0);
}
#glass.right canvas {
transform: translate(180px, 0);
}
#glass:before {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
transform: translate(calc(-50% + 130px), calc(130px - var(--reticle-size) / 2));
box-sizing: border-box;
border: 1px solid black;
width: var(--reticle-size);
height: var(--reticle-size);
}
#glass:after {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
transform: translate(calc(-50% + 130px), calc(129px - var(--reticle-size) / 2));
box-sizing: border-box;
border: 1px solid white;
width: calc(var(--reticle-size) + 2px);
height: calc(var(--reticle-size) + 2px);
}
:host(.hidden) canvas {
opacity: 0;
}
</style>
<slot></slot>
<div id="glass"
class="${this.glassPosition}"
style="transform: translate(${this.position.x}px, ${this.position.y}px); --reticle-size: ${this.reticleSize}px"
="${() => this.toggleXRay()}">
<canvas style="opacity: ${this.xRay ? 0 : 1};" width="240" height="240">
</div>
</canvas>
`;
}
}
__decorate([
property({ type: Object })
], MagnifyingGlass.prototype, "imageAccessor", void 0);
__decorate([
property({ type: Object })
], MagnifyingGlass.prototype, "pixel", void 0);
__decorate([
property({ type: String })
], MagnifyingGlass.prototype, "direction", void 0);
__decorate([
property({ type: Object })
], MagnifyingGlass.prototype, "position", void 0);
__decorate([
property({ type: Boolean })
], MagnifyingGlass.prototype, "xRay", void 0);
__decorate([
property({ type: Number })
], MagnifyingGlass.prototype, "reticleSize", void 0);
customElements.define('magnifying-glass', MagnifyingGlass);
//# sourceMappingURL=magnifying-glass.js.map