3d-grass-title
Version:
A customizable 3D grass-textured title web component using Lit + TypeScript + Three.js
684 lines (673 loc) • 24.3 kB
JavaScript
import { css as Z, LitElement as V, html as K } from "lit";
import * as d from "three";
import { Loader as X, FileLoader as Q, ShapePath as Y } from "three";
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
const tt = (i) => (t, e) => {
e !== void 0 ? e.addInitializer(() => {
customElements.define(i, t);
}) : customElements.define(i, t);
};
/**
* @license
* Copyright 2019 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
const F = globalThis, U = F.ShadowRoot && (F.ShadyCSS === void 0 || F.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype, j = Symbol(), D = /* @__PURE__ */ new WeakMap();
let et = class {
constructor(t, e, s) {
if (this._$cssResult$ = !0, s !== j) throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");
this.cssText = t, this.t = e;
}
get styleSheet() {
let t = this.o;
const e = this.t;
if (U && t === void 0) {
const s = e !== void 0 && e.length === 1;
s && (t = D.get(e)), t === void 0 && ((this.o = t = new CSSStyleSheet()).replaceSync(this.cssText), s && D.set(e, t));
}
return t;
}
toString() {
return this.cssText;
}
};
const st = (i) => new et(typeof i == "string" ? i : i + "", void 0, j), it = (i, t) => {
if (U) i.adoptedStyleSheets = t.map((e) => e instanceof CSSStyleSheet ? e : e.styleSheet);
else for (const e of t) {
const s = document.createElement("style"), r = F.litNonce;
r !== void 0 && s.setAttribute("nonce", r), s.textContent = e.cssText, i.appendChild(s);
}
}, L = U ? (i) => i : (i) => i instanceof CSSStyleSheet ? ((t) => {
let e = "";
for (const s of t.cssRules) e += s.cssText;
return st(e);
})(i) : i;
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
const { is: rt, defineProperty: nt, getOwnPropertyDescriptor: ot, getOwnPropertyNames: at, getOwnPropertySymbols: ht, getPrototypeOf: lt } = Object, M = globalThis, k = M.trustedTypes, ct = k ? k.emptyScript : "", dt = M.reactiveElementPolyfillSupport, x = (i, t) => i, A = { toAttribute(i, t) {
switch (t) {
case Boolean:
i = i ? ct : null;
break;
case Object:
case Array:
i = i == null ? i : JSON.stringify(i);
}
return i;
}, fromAttribute(i, t) {
let e = i;
switch (t) {
case Boolean:
e = i !== null;
break;
case Number:
e = i === null ? null : Number(i);
break;
case Object:
case Array:
try {
e = JSON.parse(i);
} catch {
e = null;
}
}
return e;
} }, I = (i, t) => !rt(i, t), N = { attribute: !0, type: String, converter: A, reflect: !1, useDefault: !1, hasChanged: I };
Symbol.metadata ??= Symbol("metadata"), M.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap();
class E extends HTMLElement {
static addInitializer(t) {
this._$Ei(), (this.l ??= []).push(t);
}
static get observedAttributes() {
return this.finalize(), this._$Eh && [...this._$Eh.keys()];
}
static createProperty(t, e = N) {
if (e.state && (e.attribute = !1), this._$Ei(), this.prototype.hasOwnProperty(t) && ((e = Object.create(e)).wrapped = !0), this.elementProperties.set(t, e), !e.noAccessor) {
const s = Symbol(), r = this.getPropertyDescriptor(t, s, e);
r !== void 0 && nt(this.prototype, t, r);
}
}
static getPropertyDescriptor(t, e, s) {
const { get: r, set: o } = ot(this.prototype, t) ?? { get() {
return this[e];
}, set(n) {
this[e] = n;
} };
return { get: r, set(n) {
const a = r?.call(this);
o?.call(this, n), this.requestUpdate(t, a, s);
}, configurable: !0, enumerable: !0 };
}
static getPropertyOptions(t) {
return this.elementProperties.get(t) ?? N;
}
static _$Ei() {
if (this.hasOwnProperty(x("elementProperties"))) return;
const t = lt(this);
t.finalize(), t.l !== void 0 && (this.l = [...t.l]), this.elementProperties = new Map(t.elementProperties);
}
static finalize() {
if (this.hasOwnProperty(x("finalized"))) return;
if (this.finalized = !0, this._$Ei(), this.hasOwnProperty(x("properties"))) {
const e = this.properties, s = [...at(e), ...ht(e)];
for (const r of s) this.createProperty(r, e[r]);
}
const t = this[Symbol.metadata];
if (t !== null) {
const e = litPropertyMetadata.get(t);
if (e !== void 0) for (const [s, r] of e) this.elementProperties.set(s, r);
}
this._$Eh = /* @__PURE__ */ new Map();
for (const [e, s] of this.elementProperties) {
const r = this._$Eu(e, s);
r !== void 0 && this._$Eh.set(r, e);
}
this.elementStyles = this.finalizeStyles(this.styles);
}
static finalizeStyles(t) {
const e = [];
if (Array.isArray(t)) {
const s = new Set(t.flat(1 / 0).reverse());
for (const r of s) e.unshift(L(r));
} else t !== void 0 && e.push(L(t));
return e;
}
static _$Eu(t, e) {
const s = e.attribute;
return s === !1 ? void 0 : typeof s == "string" ? s : typeof t == "string" ? t.toLowerCase() : void 0;
}
constructor() {
super(), this._$Ep = void 0, this.isUpdatePending = !1, this.hasUpdated = !1, this._$Em = null, this._$Ev();
}
_$Ev() {
this._$ES = new Promise((t) => this.enableUpdating = t), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t) => t(this));
}
addController(t) {
(this._$EO ??= /* @__PURE__ */ new Set()).add(t), this.renderRoot !== void 0 && this.isConnected && t.hostConnected?.();
}
removeController(t) {
this._$EO?.delete(t);
}
_$E_() {
const t = /* @__PURE__ */ new Map(), e = this.constructor.elementProperties;
for (const s of e.keys()) this.hasOwnProperty(s) && (t.set(s, this[s]), delete this[s]);
t.size > 0 && (this._$Ep = t);
}
createRenderRoot() {
const t = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions);
return it(t, this.constructor.elementStyles), t;
}
connectedCallback() {
this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(!0), this._$EO?.forEach((t) => t.hostConnected?.());
}
enableUpdating(t) {
}
disconnectedCallback() {
this._$EO?.forEach((t) => t.hostDisconnected?.());
}
attributeChangedCallback(t, e, s) {
this._$AK(t, s);
}
_$ET(t, e) {
const s = this.constructor.elementProperties.get(t), r = this.constructor._$Eu(t, s);
if (r !== void 0 && s.reflect === !0) {
const o = (s.converter?.toAttribute !== void 0 ? s.converter : A).toAttribute(e, s.type);
this._$Em = t, o == null ? this.removeAttribute(r) : this.setAttribute(r, o), this._$Em = null;
}
}
_$AK(t, e) {
const s = this.constructor, r = s._$Eh.get(t);
if (r !== void 0 && this._$Em !== r) {
const o = s.getPropertyOptions(r), n = typeof o.converter == "function" ? { fromAttribute: o.converter } : o.converter?.fromAttribute !== void 0 ? o.converter : A;
this._$Em = r;
const a = n.fromAttribute(e, o.type);
this[r] = a ?? this._$Ej?.get(r) ?? a, this._$Em = null;
}
}
requestUpdate(t, e, s) {
if (t !== void 0) {
const r = this.constructor, o = this[t];
if (s ??= r.getPropertyOptions(t), !((s.hasChanged ?? I)(o, e) || s.useDefault && s.reflect && o === this._$Ej?.get(t) && !this.hasAttribute(r._$Eu(t, s)))) return;
this.C(t, e, s);
}
this.isUpdatePending === !1 && (this._$ES = this._$EP());
}
C(t, e, { useDefault: s, reflect: r, wrapped: o }, n) {
s && !(this._$Ej ??= /* @__PURE__ */ new Map()).has(t) && (this._$Ej.set(t, n ?? e ?? this[t]), o !== !0 || n !== void 0) || (this._$AL.has(t) || (this.hasUpdated || s || (e = void 0), this._$AL.set(t, e)), r === !0 && this._$Em !== t && (this._$Eq ??= /* @__PURE__ */ new Set()).add(t));
}
async _$EP() {
this.isUpdatePending = !0;
try {
await this._$ES;
} catch (e) {
Promise.reject(e);
}
const t = this.scheduleUpdate();
return t != null && await t, !this.isUpdatePending;
}
scheduleUpdate() {
return this.performUpdate();
}
performUpdate() {
if (!this.isUpdatePending) return;
if (!this.hasUpdated) {
if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) {
for (const [r, o] of this._$Ep) this[r] = o;
this._$Ep = void 0;
}
const s = this.constructor.elementProperties;
if (s.size > 0) for (const [r, o] of s) {
const { wrapped: n } = o, a = this[r];
n !== !0 || this._$AL.has(r) || a === void 0 || this.C(r, void 0, o, a);
}
}
let t = !1;
const e = this._$AL;
try {
t = this.shouldUpdate(e), t ? (this.willUpdate(e), this._$EO?.forEach((s) => s.hostUpdate?.()), this.update(e)) : this._$EM();
} catch (s) {
throw t = !1, this._$EM(), s;
}
t && this._$AE(e);
}
willUpdate(t) {
}
_$AE(t) {
this._$EO?.forEach((e) => e.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = !0, this.firstUpdated(t)), this.updated(t);
}
_$EM() {
this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = !1;
}
get updateComplete() {
return this.getUpdateComplete();
}
getUpdateComplete() {
return this._$ES;
}
shouldUpdate(t) {
return !0;
}
update(t) {
this._$Eq &&= this._$Eq.forEach((e) => this._$ET(e, this[e])), this._$EM();
}
updated(t) {
}
firstUpdated(t) {
}
}
E.elementStyles = [], E.shadowRootOptions = { mode: "open" }, E[x("elementProperties")] = /* @__PURE__ */ new Map(), E[x("finalized")] = /* @__PURE__ */ new Map(), dt?.({ ReactiveElement: E }), (M.reactiveElementVersions ??= []).push("2.1.1");
/**
* @license
* Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause
*/
const ut = { attribute: !0, type: String, converter: A, reflect: !1, hasChanged: I }, pt = (i = ut, t, e) => {
const { kind: s, metadata: r } = e;
let o = globalThis.litPropertyMetadata.get(r);
if (o === void 0 && globalThis.litPropertyMetadata.set(r, o = /* @__PURE__ */ new Map()), s === "setter" && ((i = Object.create(i)).wrapped = !0), o.set(e.name, i), s === "accessor") {
const { name: n } = e;
return { set(a) {
const h = t.get.call(this);
t.set.call(this, a), this.requestUpdate(n, h, i);
}, init(a) {
return a !== void 0 && this.C(n, void 0, i, a), a;
} };
}
if (s === "setter") {
const { name: n } = e;
return function(a) {
const h = this[n];
t.call(this, a), this.requestUpdate(n, h, i);
};
}
throw Error("Unsupported decorator location: " + s);
};
function S(i) {
return (t, e) => typeof e == "object" ? pt(i, t, e) : ((s, r, o) => {
const n = r.hasOwnProperty(o);
return r.constructor.createProperty(o, s), n ? Object.getOwnPropertyDescriptor(r, o) : void 0;
})(i, t, e);
}
class mt extends X {
constructor(t) {
super(t);
}
load(t, e, s, r) {
const o = this, n = new Q(this.manager);
n.setPath(this.path), n.setRequestHeader(this.requestHeader), n.setWithCredentials(this.withCredentials), n.load(t, function(a) {
const h = o.parse(JSON.parse(a));
e && e(h);
}, s, r);
}
parse(t) {
return new ft(t);
}
}
class ft {
constructor(t) {
this.isFont = !0, this.type = "Font", this.data = t;
}
generateShapes(t, e = 100) {
const s = [], r = gt(t, e, this.data);
for (let o = 0, n = r.length; o < n; o++)
s.push(...r[o].toShapes());
return s;
}
}
function gt(i, t, e) {
const s = Array.from(i), r = t / e.resolution, o = (e.boundingBox.yMax - e.boundingBox.yMin + e.underlineThickness) * r, n = [];
let a = 0, h = 0;
for (let y = 0; y < s.length; y++) {
const m = s[y];
if (m === `
`)
a = 0, h -= o;
else {
const f = yt(m, r, a, h, e);
a += f.offsetX, n.push(f.path);
}
}
return n;
}
function yt(i, t, e, s, r) {
const o = r.glyphs[i] || r.glyphs["?"];
if (!o) {
console.error('THREE.Font: character "' + i + '" does not exists in font family ' + r.familyName + ".");
return;
}
const n = new Y();
let a, h, y, m, f, w, _, $;
if (o.o) {
const l = o._cachedOutline || (o._cachedOutline = o.o.split(" "));
for (let c = 0, P = l.length; c < P; )
switch (l[c++]) {
case "m":
a = l[c++] * t + e, h = l[c++] * t + s, n.moveTo(a, h);
break;
case "l":
a = l[c++] * t + e, h = l[c++] * t + s, n.lineTo(a, h);
break;
case "q":
y = l[c++] * t + e, m = l[c++] * t + s, f = l[c++] * t + e, w = l[c++] * t + s, n.quadraticCurveTo(f, w, y, m);
break;
case "b":
y = l[c++] * t + e, m = l[c++] * t + s, f = l[c++] * t + e, w = l[c++] * t + s, _ = l[c++] * t + e, $ = l[c++] * t + s, n.bezierCurveTo(f, w, _, $, y, m);
break;
}
}
return { offsetX: o.ha * t, path: n };
}
function vt(i, t = 500, e = 1, s) {
const r = "Arial", n = document.createElement("canvas"), a = n.getContext("2d"), h = i.split(`
`), y = h.sort((u, g) => g.length - u.length)[0].length, m = 100 * 0.7 * y, f = h.length * 100;
n.width = m, n.height = f, a.font = `bold 100px ${r}`, a.fillStyle = "#2a9d8f", a.clearRect(0, 0, n.width, n.height), h.forEach((u, g) => {
a.fillText(u, 0, (g + 0.8) * f / h.length);
});
const w = [], _ = Math.max(1, Math.round(10 - t / 150)), $ = a.getImageData(
0,
0,
n.width,
n.height
);
for (let u = 0; u < n.height; u += _)
for (let g = 0; g < n.width; g += _)
$.data[(g + u * n.width) * 4] > 0 && w.push({ x: g, y: u });
const l = new d.ConeGeometry(
0.02 * e,
0.08 * e,
8
), c = new d.ShaderMaterial({
uniforms: {
uTime: { value: 0 },
uColor: { value: new d.Color(4881497) },
// Will be updated by component
uLightIntensity: { value: 1.5 },
// Will be updated by component
uSpread: { value: 0 }
// For click animation
},
vertexShader: `
uniform float uTime;
uniform float uSpread;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
vNormal = normalize(normalMatrix * normal);
vPosition = position;
vec3 pos = position;
// Add subtle wind movement based on instance ID
float windX = sin(uTime * 2.0 + float(gl_InstanceID) * 0.1) * 0.01;
float windY = sin(uTime * 1.5 + float(gl_InstanceID) * 0.15) * 0.005;
float windZ = cos(uTime * 1.8 + float(gl_InstanceID) * 0.05) * 0.003;
pos.x += windX;
pos.y += windY;
pos.z += windZ;
// Add spread effect for click animation
vec3 spreadOffset = vec3(
sin(float(gl_InstanceID) * 0.5) * uSpread * 5.0,
cos(float(gl_InstanceID) * 0.3) * uSpread * 5.0,
sin(float(gl_InstanceID) * 0.8) * uSpread * 2.0
);
vec4 mvPosition = modelViewMatrix * instanceMatrix * vec4(pos + spreadOffset, 1.0);
gl_Position = projectionMatrix * mvPosition;
}
`,
fragmentShader: `
uniform vec3 uColor;
uniform float uLightIntensity;
varying vec3 vNormal;
varying vec3 vPosition;
void main() {
// Simple directional lighting
vec3 lightDir = normalize(vec3(1.0, 1.0, 1.0));
float NdotL = max(dot(normalize(vNormal), lightDir), 0.0);
float diffuse = 0.3 + 0.7 * NdotL; // Ambient + diffuse
// Apply lighting and intensity
vec3 finalColor = uColor * diffuse * uLightIntensity;
gl_FragColor = vec4(finalColor, 1.0);
}
`
}), P = w.length, b = new d.InstancedMesh(
l,
c,
P
), O = s.boundingBox, z = (O.max.x - O.min.x) / (m * 0.8), C = new d.Matrix4(), R = new d.Color();
for (let u = 0; u < P; u++) {
const g = w[u], q = (g.x - m / 2) * z, B = -(g.y - f / 2) * z, G = O.max.z + 0.05, H = Math.random() * Math.PI * 0.3, J = Math.random() * Math.PI * 2, W = Math.random() * Math.PI * 0.3, T = 0.8 + Math.random() * 0.4;
C.makeRotationFromEuler(
new d.Euler(H, J, W)
), C.scale(new d.Vector3(T, T, T)), C.setPosition(q, B, G), b.setMatrixAt(u, C), R.setHSL(0.25 + Math.random() * 0.05, 0.7, 0.3 + Math.random() * 0.2), b.setColorAt(u, R);
}
return b.instanceMatrix.needsUpdate = !0, b.instanceColor && (b.instanceColor.needsUpdate = !0), b;
}
var St = Object.defineProperty, wt = Object.getOwnPropertyDescriptor, v = (i, t, e, s) => {
for (var r = s > 1 ? void 0 : s ? wt(t, e) : t, o = i.length - 1, n; o >= 0; o--)
(n = i[o]) && (r = (s ? n(t, e, r) : n(r)) || r);
return s && r && St(t, e, r), r;
};
let p = class extends V {
constructor() {
super(...arguments), this.text = "Welcome", this.color = "#c5e194", this.lightIntensity = 1.2, this.rotation = [0, 0, 0], this.cameraDistance = 10, this.grassDensity = 800, this.grassHeight = 1.2, this.isAnimating = !1, this.animateScene = () => {
this.animationId = requestAnimationFrame(this.animateScene);
const i = performance.now() * 1e-3;
if (this.grassField && this.grassField.material) {
const t = this.grassField.material;
t.uniforms && t.uniforms.uTime && (t.uniforms.uTime.value = i);
}
this.renderer.render(this.scene, this.camera);
}, this.handleClick = () => {
!this.link || this.isAnimating || (this.isAnimating = !0, this.startParticleSpreadAnimation());
}, this.startParticleSpreadAnimation = () => {
if (!this.grassField || !this.grassField.material) return;
const t = this.grassField.material.uniforms;
if (t.uSpread) {
const e = performance.now(), s = 800, r = () => {
const o = performance.now() - e, n = Math.min(o / s, 1), a = 1 - Math.pow(1 - n, 3);
t.uSpread.value = a, n < 1 ? requestAnimationFrame(r) : setTimeout(() => {
this.startParticleReturnAnimation();
}, 200);
};
r();
}
}, this.startParticleReturnAnimation = () => {
if (!this.grassField || !this.grassField.material) return;
const t = this.grassField.material.uniforms;
if (t.uSpread) {
const e = performance.now(), s = 600, r = () => {
const o = performance.now() - e, n = Math.min(o / s, 1), a = 1 - Math.pow(1 - n, 2);
t.uSpread.value = 1 - a, n < 1 ? requestAnimationFrame(r) : (this.isAnimating = !1, this.link && (window.location.href = this.link));
};
r();
}
};
}
render() {
return K`<canvas ="${this.handleClick}"></canvas>`;
}
firstUpdated() {
this.canvas = this.shadowRoot.querySelector("canvas"), this.initThreeJS(), this.loadFont(), this.setupResizeObserver();
}
disconnectedCallback() {
super.disconnectedCallback(), this.animationId && cancelAnimationFrame(this.animationId), this.resizeObserver && this.resizeObserver.disconnect(), this.cleanup();
}
initThreeJS() {
this.scene = new d.Scene(), this.scene.background = new d.Color(0);
const i = this.canvas.getBoundingClientRect();
this.camera = new d.PerspectiveCamera(
75,
i.width / i.height,
0.1,
1e3
), this.camera.position.set(0, 0, this.cameraDistance), this.renderer = new d.WebGLRenderer({
canvas: this.canvas,
antialias: !0,
alpha: !0
}), this.renderer.setSize(i.width, i.height), this.renderer.setPixelRatio(window.devicePixelRatio), this.light = new d.DirectionalLight(16777215, this.lightIntensity), this.light.position.set(1, 1, 1), this.scene.add(this.light);
const t = new d.AmbientLight(4210752, 0.4);
this.scene.add(t);
}
loadFont() {
this.fontLoader = new mt();
const i = this.fontUrl || "https://threejs.org/examples/fonts/helvetiker_regular.typeface.json";
this.fontLoader.load(
i,
async (t) => {
this.font = t, await this.createGrassField(), this.animationId || this.animateScene();
},
void 0,
async (t) => {
console.error("Font loading error:", t), this.animationId || this.animateScene();
}
);
}
async createGrassField() {
this.grassField && (this.scene.remove(this.grassField), this.grassField.geometry.dispose(), this.grassField.material && (Array.isArray(this.grassField.material) ? this.grassField.material.forEach((t) => t.dispose()) : this.grassField.material.dispose()));
const i = this.scene.children.find(
(t) => t.userData.isTextMesh
);
i && this.scene.remove(i);
try {
const { TextGeometry: t } = await import("./TextGeometry-Cb4kkJR_.js"), e = new t(this.text, {
font: this.font,
size: 1,
height: 0.5,
curveSegments: 12,
bevelEnabled: !0,
bevelThickness: 0.1,
bevelSize: 0.05,
bevelOffset: 0,
bevelSegments: 5
});
e.computeBoundingBox();
const s = -0.5 * (e.boundingBox.max.x - e.boundingBox.min.x), r = -0.5 * (e.boundingBox.max.y - e.boundingBox.min.y);
if (e.translate(s, r, 0), this.grassField = vt(
this.text,
this.grassDensity,
this.grassHeight,
e
), this.scene.add(this.grassField), this.grassField.material instanceof d.ShaderMaterial) {
const n = this.grassField.material.uniforms;
n.uColor && (n.uColor.value = new d.Color(this.color)), n.uLightIntensity && (n.uLightIntensity.value = this.lightIntensity);
}
} catch (t) {
console.error("Error creating grass text:", t);
}
}
setupResizeObserver() {
this.resizeObserver = new ResizeObserver(() => {
this.handleResize();
}), this.resizeObserver.observe(this);
}
handleResize() {
const i = this.canvas.getBoundingClientRect();
this.camera.aspect = i.width / i.height, this.camera.updateProjectionMatrix(), this.renderer.setSize(i.width, i.height);
}
cleanup() {
this.grassField && (this.scene.remove(this.grassField), this.grassField.geometry.dispose(), this.grassField.material && (Array.isArray(this.grassField.material) ? this.grassField.material.forEach((i) => i.dispose()) : this.grassField.material.dispose())), this.renderer && this.renderer.dispose();
}
updated(i) {
if (i.has("text") && this.font && this.createGrassField(), (i.has("grassDensity") || i.has("grassHeight")) && this.font && this.createGrassField(), i.has("color") && this.grassField && this.grassField.material) {
const e = this.grassField.material.uniforms;
e.uColor && (e.uColor.value = new d.Color(this.color));
}
if (i.has("lightIntensity") && (this.light && (this.light.intensity = this.lightIntensity), this.grassField && this.grassField.material)) {
const e = this.grassField.material.uniforms;
e.uLightIntensity && (e.uLightIntensity.value = this.lightIntensity);
}
i.has("rotation") && this.grassField && this.grassField.rotation.set(
this.rotation[0],
this.rotation[1],
this.rotation[2]
), i.has("cameraDistance") && this.camera && this.camera.position.setZ(this.cameraDistance), i.has("fontUrl") && this.loadFont();
}
};
p.styles = Z`
:host {
display: block;
width: 100%;
height: 25rem;
position: relative;
}
canvas {
width: 100%;
height: 100%;
display: block;
cursor: pointer;
}
`;
v([
S({ type: String, reflect: !0 })
], p.prototype, "text", 2);
v([
S({ type: String, reflect: !0 })
], p.prototype, "color", 2);
v([
S({
type: Number,
reflect: !0,
attribute: "light-intensity"
})
], p.prototype, "lightIntensity", 2);
v([
S({
type: Array,
converter: {
fromAttribute: (i) => {
try {
return JSON.parse(i);
} catch {
return [0, 0, 0];
}
},
toAttribute: (i) => JSON.stringify(i)
}
})
], p.prototype, "rotation", 2);
v([
S({
type: Number,
reflect: !0,
attribute: "camera-distance"
})
], p.prototype, "cameraDistance", 2);
v([
S({
type: String,
reflect: !0,
attribute: "font-url"
})
], p.prototype, "fontUrl", 2);
v([
S({
type: Number,
reflect: !0,
attribute: "grass-density"
})
], p.prototype, "grassDensity", 2);
v([
S({
type: Number,
reflect: !0,
attribute: "grass-height"
})
], p.prototype, "grassHeight", 2);
v([
S({
type: String,
reflect: !0
})
], p.prototype, "link", 2);
p = v([
tt("grass-title")
], p);
export {
p as GrassTitle,
vt as createGrassFieldFromTextCanvas
};