Skip to content

Commit

Permalink
Merge pull request #39 from numbersprotocol/feature-customize-color
Browse files Browse the repository at this point in the history
feat(src): customize the color of the Eye
  • Loading branch information
olgahaha authored Nov 8, 2024
2 parents 0cac6a6 + a0819b4 commit 2f714eb
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 59 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ Visit the [interactive playground](https://playcode.io/capture_eye_demo) for the
| `nid` | Yes | The unique [Nid](https://docs.numbersprotocol.io/introduction/numbers-protocol/defining-web3-assets/numbers-id-nid) of the asset. <br> `<capture-eye nid="bafybeief3yriouin54tzub5otnzka6muacrsu32tl2vxnaexgffizdxxqy"></capture-eye>` |
| `layout` | No | Decides which layout to display. Default value is `original`. Additional option includes `curated`. <br> `<capture-eye nid="..." layout="curated"></capture-eye>` |
| `visibility` | No | Visibility behavior. Default value is `hover`, showing Eye on mouse hover. Setting it to option `always` will make the Eye always shown. This attribute is `always` and cannot be customized on mobile devices. <br> `<capture-eye nid="..." visibility="always"></capture-eye>` |
| `color` | No | The widget color. Default value is #377dde (blue), and for mobile, the default value is #333333 (gray). <br> `<capture-eye nid="..." color="#c04240"></capture-eye>` |
| `cz-title` | No | Override the copyright zone title. <br> `<capture-eye nid="..." cz-title="collected by"></capture-eye>` |
| eng-img | No | Sets the image for the engagement zone banner. Recommended dimensions: `320x120 px`. Supports multiple `eng-img` and `eng-link` pairs for rotating banners. If multiple pairs are provided by using comma to seperate each URL entry, the banner will rotate every 5 seconds. Ensure that the number of `eng-img` matches the number of `eng-link` entries. Use URL encoding to replace commas with `%2C` in the URLs. <br> `<capture-eye nid="..." eng-img="https://my.image.url/image1.png, https://my.image.url/image2.png"></capture-eye>` |
| eng-link | No | Sets the URL for the engagement zone banner link. Each `eng-link` should correspond to an `eng-img` for proper pairing in rotating banners, following the same comma-separated rule. <br> `<capture-eye nid="..." eng-link="https://my.website.url1, https://my.website.url2"></capture-eye>` |
| `eng-img` | No | Sets the image for the engagement zone banner. Recommended dimensions: `320x120 px`. Supports multiple `eng-img` and `eng-link` pairs for rotating banners. If multiple pairs are provided by using comma to seperate each URL entry, the banner will rotate every 5 seconds. Ensure that the number of `eng-img` matches the number of `eng-link` entries. Use URL encoding to replace commas with `%2C` in the URLs. <br> `<capture-eye nid="..." eng-img="https://my.image.url/image1.png, https://my.image.url/image2.png"></capture-eye>` |
| `eng-link` | No | Sets the URL for the engagement zone banner link. Each `eng-link` should correspond to an `eng-img` for proper pairing in rotating banners, following the same comma-separated rule. <br> `<capture-eye nid="..." eng-link="https://my.website.url1, https://my.website.url2"></capture-eye>` |
| `action-button-text` | No | Override the default action button text (`View More`). <br> `<capture-eye nid="..." action-button-text="Collect"></capture-eye>` |
| `action-button-link` | No | Override the default action button link to Capture website. <br> `<capture-eye nid="..." action-button-link="https://my.website.url"></capture-eye>` |

Expand Down
4 changes: 0 additions & 4 deletions assets/icons/capture-eye-close-gray.svg

This file was deleted.

Binary file removed assets/icons/capture-eye-close-icon.png
Binary file not shown.
16 changes: 0 additions & 16 deletions assets/icons/capture-eye-gray.svg

This file was deleted.

1 change: 1 addition & 0 deletions dev/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<div class="grid-container">
<capture-eye
nid="bafybeifksqe7orsgtfnly5j3okltqi3iyt3k2pptnlfyre62jpfzxftsju"
color="#c04240"
cz-title="Collected By"
eng-img="https://static-cdn.numbersprotocol.io/capture-eye/capture-ad.png, https://static-cdn.numbersprotocol.io/collab/defiance_media_banner.webp"
eng-link="https://captureapp.xyz, https://defiance.media/"
Expand Down
2 changes: 1 addition & 1 deletion examples/bubble/capture-eye-header.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@numbersprotocol/capture-eye/dist/capture-eye.bundled.js"
></script>
></script>
132 changes: 113 additions & 19 deletions src/capture-eye.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LitElement, html } from 'lit';
import { LitElement, HTMLTemplateResult, html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { Constant } from './constant.js';
import { getCaptureEyeStyles } from './capture-eye-styles.js';
Expand Down Expand Up @@ -32,6 +32,12 @@ export class CaptureEye extends LitElement {
@property({ type: String })
visibility = Constant.visibility.hover;

/**
* Set color: default is #377dde, and for mobile, the default is #333333.
*/
@property({ type: String })
color = '';

/**
* Customizable copyright zone title.
*/
Expand Down Expand Up @@ -91,25 +97,28 @@ export class CaptureEye extends LitElement {
}

private buttonTemplate() {
if (!this.nid) {
return html``;
}

const mobile = isMobile();
return this.nid
? html`
<div
class="capture-eye-button ${this.visibility ===
Constant.visibility.always || mobile
? 'full-visibility'
: ''}"
@click=${this.openEye}
>
<img
src=${mobile
? Constant.url.captureEyeMobileIcon
: Constant.url.captureEyeIcon}
alt="Capture Eye"
/>
</div>
`
: null;
const color = this.color
? this.color
: mobile
? Constant.color.mobileEye
: Constant.color.defaultEye;
const size = mobile ? 24 : 32;
return html`
<div
class="capture-eye-button ${this.visibility ===
Constant.visibility.always || mobile
? 'full-visibility'
: ''}"
@click=${this.openEye}
>
${this.generateCaptureEyeSvg(color, size)}
</div>
`;
}

override render() {
Expand Down Expand Up @@ -140,6 +149,7 @@ export class CaptureEye extends LitElement {
const modalOptions = {
nid: this.nid,
layout: this.layout,
color: this.color,
copyrightZoneTitle: this.copyrightZoneTitle,
engagementZones: this.engagementZones,
actionButtonText: this.actionButtonText,
Expand All @@ -161,6 +171,90 @@ export class CaptureEye extends LitElement {
}
}

private generateCaptureEyeSvg(
color: string, size: number
): HTMLTemplateResult {
return html`
<svg
style="--eye-color: ${color};" width="${size}" height="${size}"
viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_640_264)">
<path
d="M11.9821 23.8844C18.5457 23.8844 23.8665 18.5635 23.8665
11.9999C23.8665 5.43633 18.5457 0.115479 11.9821 0.115479C5.4185
0.115479 0.0976562 5.43633 0.0976562 11.9999C0.0976562 18.5635
5.4185 23.8844 11.9821 23.8844Z"
style="fill: var(--eye-color, #377dde);"
/>
<path
d="M18.4909 17.6401C18.4909 17.8801 18.3931 18.0956 18.2375
18.2534C18.0798 18.4112 17.8642 18.5068 17.6242
18.5068H15.542V20.3401H16.8131C17.2042 20.3401 17.5775 20.1845
17.8531 19.909L19.8931 17.869C20.1687 17.5934 20.3242 17.2179
20.3242 16.829V15.5579H18.4909V17.6401Z"
fill="white"
/>
<path
d="M5.72876 18.2556C5.57098 18.0978 5.47542 17.8823 5.47542
17.6423V15.5601H3.64209V16.8312C3.64209 17.2223 3.79765 17.5956
4.0732 17.8712L6.1132 19.9112C6.38876 20.1867 6.76431 20.3423
7.1532 20.3423H8.42431V18.5089H6.34209C6.10209 18.5089 5.88653
18.4134 5.72876 18.2556Z"
fill="white"
/>
<path
d="M5.47347 6.35991C5.47347 6.11991 5.57125 5.90436 5.7268
5.74658C5.88458 5.5888 6.10014 5.49325 6.34014
5.49325H8.42236V3.65991H7.15125C6.76014 3.65991 6.3868 3.81547
6.11125 4.09102L4.07125 6.13102C3.79569 6.40658 3.64014 6.78213
3.64014 7.17102V8.44436H5.47347V6.35991Z"
fill="white"
/>
<path
d="M19.8911 6.13102L17.8512 4.09102C17.5756 3.81547 17.2 3.65991
16.8112 3.65991H15.54V5.49325H17.6223C17.8623 5.49325 18.0778
5.59102 18.2356 5.74658C18.3934 5.90436 18.4889 6.11991 18.4889
6.35991V8.44213H20.3223V7.17102C20.3223 6.78213 20.1689 6.4088
19.8911 6.13102Z"
fill="white"
/>
<path
d="M19.1002 12.3777L19.3069 11.9999L19.1002 11.6221C18.4113 10.3621
17.4024 9.30879 16.178 8.56657C14.9558 7.82657 13.518 7.3999
11.9847 7.3999H11.9802C10.4469 7.3999 9.00909 7.82657 7.78465
8.56879C6.56021 9.31101 5.5491 10.3666 4.86243 11.6243L4.65576
12.0021L4.86243 12.3799C5.55132 13.6399 6.56021 14.6932 7.78465
15.4355C9.00687 16.1777 10.4469 16.6043 11.978
16.6043H11.9824C13.5158 16.6043 14.9535 16.1777 16.178
15.4355C17.4024 14.691 18.4135 13.6377 19.1002 12.3777ZM11.9824
15.031C11.0513 15.031 10.1713 14.8377 9.37132 14.4888C9.10465
14.3732 8.84687 14.2399 8.60021 14.0888C7.77576 13.5888 7.07132
12.911 6.53798 12.1088L6.46687 11.9999L6.54021 11.891C7.07354
11.0888 7.77798 10.411 8.60243 9.91101C9.5891 9.31324 10.7424
8.96879 11.9847 8.96879C13.2247 8.96879 14.378 9.31324 15.3669
9.91101C16.1913 10.411 16.8958 11.0888 17.4291 11.891L17.5024
11.9999L17.4291 12.1088C16.8958 12.911 16.1913 13.5888 15.3669
14.0888C14.3758 14.6866 13.2224 15.031 11.9824 15.031Z"
fill="white"
/>
<path
d="M11.9822 13.8934C13.0279 13.8934 13.8755 13.0457 13.8755
12C13.8755 10.9544 13.0279 10.1067 11.9822 10.1067C10.9365 10.1067
10.0889 10.9544 10.0889 12C10.0889 13.0457 10.9365 13.8934 11.9822
13.8934Z"
fill="white"
/>
</g>
<defs>
<clipPath id="clip0_640_264">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>
`;
}

private getButtonElement(): HTMLElement {
return this.shadowRoot?.querySelector('.capture-eye-button') as HTMLElement;
}
Expand Down
19 changes: 11 additions & 8 deletions src/constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ interface Url {
profile: string;
showcase: string;
collect: string;
captureEyeIcon: string;
captureEyeMobileIcon: string;
closeIcon: string;
mobileCloseIcon: string;
fontFaceCssUrl: string;
blockchainIcon: string;
txIcon: string;
Expand All @@ -32,17 +28,24 @@ interface ConstantType {
text: Text;
layout: Layout;
visibility: Visibility;
color: Color;
}

interface Layout {
original: string;
curated: string;
}

interface Visibility {
hover: string;
always: string;
}

interface Color {
defaultEye: string;
mobileEye: string;
}

const numbersCdnUrl = 'https://static-cdn.numbersprotocol.io';

export const Constant: ConstantType = {
Expand All @@ -56,10 +59,6 @@ export const Constant: ConstantType = {
profile: 'https://asset.captureapp.xyz',
showcase: 'https://dashboard.captureapp.xyz/showcase',
collect: 'https://captureappiframe.numbersprotocol.io/checkout',
captureEyeIcon: `${numbersCdnUrl}/capture-eye-blue-32x32.png`,
captureEyeMobileIcon: `${numbersCdnUrl}/capture-eye/capture-eye-gray.svg`,
closeIcon: `${numbersCdnUrl}/capture-eye/capture-eye-close-icon.png`,
mobileCloseIcon: `${numbersCdnUrl}/capture-eye/capture-eye-close-gray.svg`,
fontFaceCssUrl: `${numbersCdnUrl}/fonts/degular.css`,
blockchainIcon: `${numbersCdnUrl}/capture-eye/capture-eye-blockchain-icon.svg`,
txIcon: `${numbersCdnUrl}/capture-eye/capture-eye-tx-icon.svg`,
Expand All @@ -81,4 +80,8 @@ export const Constant: ConstantType = {
hover: 'hover',
always: 'always',
},
color: {
defaultEye: '#377dde',
mobileEye: '#333333',
}
};
42 changes: 35 additions & 7 deletions src/modal/modal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LitElement, html } from 'lit';
import { LitElement, HTMLTemplateResult, html } from 'lit';
import { customElement, property, state, query } from 'lit/decorators.js';
import { getModalStyles } from './modal-styles.js';
import { Constant } from '../constant.js';
Expand All @@ -15,6 +15,28 @@ export function formatTxHash(txHash: string): string {
return `${firstPart}...${lastPart}`;
}

export function generateCaptureEyeCloseSvg(
color: string, size: number
): HTMLTemplateResult {
return html`
<svg
style="--eye-color: ${color};" width="${size}" height="${size}"
viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 24C18.6274 24 24 18.6274 24 12C24 5.37258 18.6274 0 12
0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24Z"
style="fill: var(--eye-color, #377dde);"
/>
<path
d="M17 7.875L16.125 7L12 11.125L7.875 7L7 7.875L11.125 12L7
16.125L7.875 17L12 12.875L16.125 17L17 16.125L12.875 12L17 7.875Z"
fill="white"
/>
</svg>
`;
}

export interface EngagementZone {
image: string;
link: string;
Expand All @@ -23,6 +45,7 @@ export interface EngagementZone {
export interface ModalOptions {
nid: string;
layout?: string;
color?: string;
copyrightZoneTitle?: string;
engagementZones?: EngagementZone[];
actionButtonText?: string;
Expand All @@ -38,6 +61,7 @@ export class CaptureEyeModal extends LitElement {
@property({ type: String }) layout = Constant.layout.original;
@property({ type: Boolean }) modalHidden = true;

@state() protected _color = '';
@state() protected _copyrightZoneTitle = '';
@state() protected _engagementZones: EngagementZone[] = [];
@state() protected _engagementZoneIndex = 0;
Expand Down Expand Up @@ -79,6 +103,7 @@ export class CaptureEyeModal extends LitElement {
updateModalOptions(options: ModalOptions) {
if (options.nid) this.nid = options.nid;
if (options.layout) this.layout = options.layout;
if (options.color) this._color = options.color;
if (options.copyrightZoneTitle)
this._copyrightZoneTitle = options.copyrightZoneTitle;
if (
Expand Down Expand Up @@ -107,6 +132,7 @@ export class CaptureEyeModal extends LitElement {
this.stopEngagementZoneRotation();
this.nid = '';
this.layout = Constant.layout.original;
this._color = '';
this._copyrightZoneTitle = '';
this._engagementZones = [];
this._engagementZoneIndex = 0;
Expand Down Expand Up @@ -445,6 +471,13 @@ export class CaptureEyeModal extends LitElement {
}

override render() {
const mobile = isMobile()
const color = this._color
? this._color
: mobile
? Constant.color.mobileEye
: Constant.color.defaultEye;
const size = mobile ? 24 : 32;
return html`
<div
class="modal ${this.modalHidden ? 'modal-hidden' : 'modal-visible'}"
Expand All @@ -463,12 +496,7 @@ export class CaptureEyeModal extends LitElement {
</div>
${this.renderEngagementZone()}
<div class="close-button" @click=${this.hideModal}>
<img
src=${isMobile()
? Constant.url.mobileCloseIcon
: Constant.url.closeIcon}
alt="Close"
/>
${generateCaptureEyeCloseSvg(color, size)}
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/test/modal_test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { html } from 'lit';
import { fixture, assert, expect } from '@open-wc/testing';
import { CaptureEyeModal, formatTxHash } from '../modal/modal';
import { CaptureEyeModal, formatTxHash, generateCaptureEyeCloseSvg } from '../modal/modal';
import { AssetModel } from '../asset/asset-model';
import interactionTracker, { TrackerEvent } from '../modal/interaction-tracker';
import sinon from 'sinon';
Expand Down Expand Up @@ -75,7 +75,7 @@ suite('capture-eye-modal', () => {
</a>
</div>
<div class="close-button close-button-hidden">
<img src="https://static-cdn.numbersprotocol.io/capture-eye/capture-eye-close-icon.png" alt="Close" />
${generateCaptureEyeCloseSvg(Constant.color.defaultEye, 32).strings.join()}
</div>
</div>
</div>
Expand Down

0 comments on commit 2f714eb

Please sign in to comment.