2.0.3 • Published 4 months ago

sectored-wheel v2.0.3

Weekly downloads
-
License
ISC
Repository
github
Last release
4 months ago

<sectored-wheel> element

Spinned Sectored Wheel

No dependencies, Web Component.

Demo / Code Example https://oleksiy-nesterov.github.io/sectored-wheel

Installation

<script type="module" src="https://oleksiy-nesterov.github.io/sectored-wheel/dist/index.js"></script>

or

npm install sectored-wheel

or

npm install git+https://github.com/oleksiy-nesterov/sectored-wheel.git#v2.0.3

Usage

/* hide not defined HTMLElements during the module loading */
*:not(:defined) {
  display: none;
}
<sectored-wheel
  colors="red;green;blue"
  rim-color="#ccc"
  onclick="this.index = Math.round(Math.random() * 2)"
  onchange="console.warn(this.index)"
  size="600px">
  <sectored-wheel-item>1</sectored-wheel-item>
  <sectored-wheel-item>2</sectored-wheel-item>
  <sectored-wheel-item>3</sectored-wheel-item>
</sectored-wheel>
const wheel = document.querySelector('sectored-wheel');

wheel.onchange = () => {
  console.log(this.index);
};

wheel.index = 3;

Configuration

Props, Methods and Attributes

Wheel's Props & AttributesDescriptionExampleDefault
indexSelected sector10
sizeWheel size200vh100px
colorsSector colorred;green;bluetransparent
strokeStroke size in px100
strokeColor, stroke-colorStroke colorred, rgba(0,0,0,0.5)transparent
paddinginset padding in pixels100
directionRotate directioncw, acwcw
azimuthWheel azimuth-90deg, 0.25turn, etc0
rotationAcceleration, rotation-accelerationhow many full rotations should be done each time21
rotationTime, rotation-timeRotation time10s, 200ms, etc5s
inRotationRead Only, allow to determine the wheel rotation
inSpinningRead Only, allow to determine the wheel spinning
spinMethod to make wheel infinity spinning
setIndexAsyncMethod to set Index async. The first parameter is an async or regular function which should return a new Index, the first parameter can be just a number. The second parameter is a minimal time of wheel spin in ms (default value is 0).
Sector's AttributesDescription
clippingClip content
colorSector color

CSS vars, which can used for custom styles

VarDescription
--countAmount of sectors
--sector-heightSector height
--sector-widthSector width
--sector-angleStroke angle

CSS classes, which can used for custom styles

ClassDescription
sectored-wheel-item.selectedSelected sector
sectored-wheel-item.preselectedDefault (preselected) sector

Integration

Angular Component Wrapper

<sectored-wheel
    #wheel
    (change)="changed($event)"
    colors="#7bbbd6;#294b7b;#cae4e3"
    size="{{'600px'}}"
    style="margin:20px;"
>
    <sectored-wheel-item
        *ngFor="let item of sectors; let index = index"
        (click)="click()"
    >
        {{index}}
    </sectored-wheel-item>
</sectored-wheel>
import {CUSTOM_ELEMENTS_SCHEMA, Component, ElementRef, Input, OnInit, ViewChild} from '@angular/core';
import {CommonModule} from '@angular/common';
import 'sectored-wheel';

@Component({
    selector: 'app-my-component',
    standalone: true,
    imports: [CommonModule],
    templateUrl: './my-component.component.html',
    styleUrl: './my-component.component.scss',
    schemas: [CUSTOM_ELEMENTS_SCHEMA], // Add CUSTOM_ELEMENTS_SCHEMA to the component
})
export class MyComponentComponent implements OnInit {
    @Input() count: number = 0;
    @ViewChild('wheel') wheel?: ElementRef<HTMLElement & { index: number }>;

    sectors: number[] = [];

    changed = (event: Event) => {
        console.log((event as CustomEvent).detail.data);
    };

    click = () => {
        if (this.wheel?.nativeElement) {
            this.wheel.nativeElement.index = Math.round(Math.random() * this.count);
        }
    };

    ngOnInit() {
        this.sectors = new Array(this.count).fill(0);
    }
}

Also, CUSTOM_ELEMENTS_SCHEMA can be added to the module

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
    ...
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class SomeModule {
    //...
}

React Component Wrapper

import {useCallback, useEffect, useMemo, useRef} from 'react';
import 'sectored-wheel/dist/sectored-wheel.min.js';

export const MyComponent = ({count}: {
  count: number
}) => {
  const wheel = useRef<HTMLElement & {
    index: number
  }>(null);

  useEffect(() => {
    if (wheel.current) {
        const el = wheel.current;
        const onChange = (event: Event) => {
            const index = (event as CustomEvent).detail?.data;
            console.log(index);
        };
        el.onchange = onChange;
        // or use event
        // el.addEventListener('change', onChange);
        // return () => {
        //   el.removeEventListener('change', onChange);
        // }
    }
  }, []);

  const sectors = useMemo(() => {
    return new Array(count).fill(0).map((_, i) => {
      return <sectored-wheel-item key={i}>{i}</sectored-wheel-item>;
    });
  }, [count]);

  const click = useCallback(() => {
    if (wheel.current) {
      wheel.current.index = Math.round(Math.random() * count);
    }
  }, [count]);

  return (
    <sectored-wheel
      ref={wheel}
      colors="#7bbbd6;#294b7b;#cae4e3"
      size="600px"
      onClick={click}
      style={{margin: '20px'}}
    >
      {sectors}
    </sectored-wheel>
  );
}

Add your wrapper name.d.ts file to the same folder, to allow React to recognize the props of the web component

import {DOMAttributes} from 'react';
import {SectoredWheelElement, SectoredWheelItemElement} from 'sectored-wheel';

type CustomElement<T> = Partial<T & DOMAttributes<T> & { children: unknown }>;

declare global {
  namespace JSX {
    interface IntrinsicElements {
      ['sectored-wheel']: CustomElement<SectoredWheelElement>;
      ['sectored-wheel-item']: CustomElement<SectoredWheelItemElement>;
    }
  }
}

Links

CodePen Playground https://codepen.io/webmotoric/pen/JjwQeQR?editors=1001

Browser support

Browsers without native custom element support require a polyfill.

  • Chrome
  • Firefox
  • Safari
  • Microsoft Edge
2.0.3

4 months ago

2.0.2

4 months ago

2.0.1

4 months ago

2.0.0

4 months ago

1.0.2

6 months ago

1.0.1

6 months ago

1.0.0

6 months ago