Skip to content

Commit

Permalink
feat: add harmonic handler
Browse files Browse the repository at this point in the history
  • Loading branch information
LKL2017 committed Dec 15, 2023
1 parent ffd85df commit b09a49a
Show file tree
Hide file tree
Showing 20 changed files with 238 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/di/particle-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {ParticleImageService} from "../services/particle-image.service";
import {ParticleService} from "../services/particle.service";

export const ParticleFactory = (route: ActivatedRoute) => {
console.log('call particle factory')
let type = '';
route.params.subscribe(params => {
type = params['type'];
Expand Down
7 changes: 5 additions & 2 deletions src/gallery/gallery-detail/gallery-detail.component.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<section class="container">
<div class="main">
<canvas id="canvas-host" #canvas></canvas>
<!-- <div class="canvas-handler"></div>-->
<div class="canvas-handler">
<span class="title">Try Some Controls</span>
<ng-component *ngComponentOutlet="getHandlerComponent(); inputs: { particleService }"></ng-component>
</div>
</div>
<button mat-raised-button color="primary" (click)="toGalleryHome()">Back</button>
<div class="footer">
<button mat-raised-button color="primary" (click)="toGalleryHome()">Back</button>
</div>
</section>
11 changes: 8 additions & 3 deletions src/gallery/gallery-detail/gallery-detail.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,19 @@
}

.canvas-handler {
flex: 0 0 120px;
flex: 1 0 120px;
margin: 0 1rem;

.title {
font-size: 1.2rem;
padding-bottom: 4px;
border-bottom: 1px solid #fff6;
}
}
}

.footer {
height: 2rem;
//background: #fff5;
margin: 1rem 0;
}

}
36 changes: 32 additions & 4 deletions src/gallery/gallery-detail/gallery-detail.component.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,31 @@
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {AfterViewInit, Component, ElementRef, Inject, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {Artifact, ArtifactToken, MOCK_ARTIFACTS} from "../../di/mock";
import {ParticleFactory} from "../../di/particle-factory";
import {ParticleGravityService} from "../../services/particle-gravity.service";
import {ParticleHarmonicService} from "../../services/particle-harmonic.service";
import {ParticleImageService} from "../../services/particle-image.service";
import {ParticleService} from "../../services/particle.service";
import {GravityHandlerComponent} from "../gallery-handler/gravity-handler/gravity-handler.component";
import {HarmonicHandlerComponent} from "../gallery-handler/harmonic-handler/harmonic-handler.component";
import {ImageHandlerComponent} from "../gallery-handler/image-handler/image-handler.component";

@Component({
selector: 'app-gallery-detail',
templateUrl: './gallery-detail.component.html',
styleUrl: './gallery-detail.component.scss',
providers: [
{ provide: ParticleService, useFactory: ParticleFactory, deps: [ActivatedRoute] }
{ provide: ParticleService, useFactory: ParticleFactory, deps: [ActivatedRoute] },
]
})
export class GalleryDetailComponent implements OnInit, AfterViewInit {
@ViewChild('canvas') canvasRef!: ElementRef;

constructor(private particleService: ParticleService,
private router: Router) {}
constructor(protected particleService: ParticleService,
private router: Router,
private route: ActivatedRoute
) {
}

ngOnInit() {
}
Expand All @@ -28,4 +38,22 @@ export class GalleryDetailComponent implements OnInit, AfterViewInit {
toGalleryHome() {
this.router.navigate(['gallery/home'])
}

// @ts-ignore
getHandlerComponent() {
let type = '';
this.route.params.subscribe(params => {
type = params['type']
});
switch (type) {
case 'harmonic':
return HarmonicHandlerComponent;
case 'gravity':
return GravityHandlerComponent;
case 'dancing':
return ImageHandlerComponent;
default:
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>gravity-handler works!</p>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { GravityHandlerComponent } from './gravity-handler.component';

describe('GravityHandlerComponent', () => {
let component: GravityHandlerComponent;
let fixture: ComponentFixture<GravityHandlerComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [GravityHandlerComponent]
})
.compileComponents();

fixture = TestBed.createComponent(GravityHandlerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Component } from '@angular/core';
import {ParticleGravityService} from "../../../services/particle-gravity.service";

@Component({
selector: 'app-gravity-handler',
templateUrl: './gravity-handler.component.html',
styleUrl: './gravity-handler.component.scss',
providers: [ParticleGravityService]
})
export class GravityHandlerComponent {
constructor(private particleGravityService: ParticleGravityService) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="handler-control-row">
<label>Composite two waves</label>
<mat-slide-toggle [(ngModel)]="isComposite" (ngModelChange)="toggleComposite()">{{ isComposite ? 'Composited' : 'Divided'}}</mat-slide-toggle>
</div>
<div class="handler-control-row">
<label>Particle Style</label>
<mat-radio-group [(ngModel)]="particleStyle" (ngModelChange)="setParticleParticle($event)">
<mat-radio-button value="circle">
Circle
</mat-radio-button>
<mat-radio-button value="rect">
Rectangle
</mat-radio-button>
</mat-radio-group>

</div>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { HarmonicHandlerComponent } from './harmonic-handler.component';

describe('HarmonicHandlerComponent', () => {
let component: HarmonicHandlerComponent;
let fixture: ComponentFixture<HarmonicHandlerComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [HarmonicHandlerComponent]
})
.compileComponents();

fixture = TestBed.createComponent(HarmonicHandlerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {Component, Input, OnInit} from '@angular/core';
import {HarmonicParticleStyle, ParticleHarmonicService} from "../../../services/particle-harmonic.service";

@Component({
selector: 'app-harmonic-handler',
templateUrl: './harmonic-handler.component.html',
styleUrl: './harmonic-handler.component.scss',
})
export class HarmonicHandlerComponent implements OnInit{
// use the output service from factory
@Input() particleService: ParticleHarmonicService;

isComposite = false;
particleStyle: HarmonicParticleStyle = "circle";

constructor() {
}

ngOnInit() {
}

toggleComposite() {
this.particleService.toggleComposite();
}

setParticleParticle(style: HarmonicParticleStyle) {
this.particleService.setParticleStyle(style);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<p>image-handler works!</p>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ImageHandlerComponent } from './image-handler.component';

describe('ImageHandlerComponent', () => {
let component: ImageHandlerComponent;
let fixture: ComponentFixture<ImageHandlerComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ImageHandlerComponent]
})
.compileComponents();

fixture = TestBed.createComponent(ImageHandlerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Component } from '@angular/core';

@Component({
selector: 'app-image-handler',
templateUrl: './image-handler.component.html',
styleUrl: './image-handler.component.scss'
})
export class ImageHandlerComponent {

}
19 changes: 17 additions & 2 deletions src/gallery/gallery.module.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {FormsModule} from "@angular/forms";
import {MatButtonModule} from "@angular/material/button";
import {MatCardModule} from "@angular/material/card";
import {MatRadioModule} from "@angular/material/radio";
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
import {GalleryDetailComponent} from "./gallery-detail/gallery-detail.component";
import {GalleryHomeComponent} from "./gallery-home/gallery-home.component";

import { GalleryRoutingModule } from './gallery-routing.module';
import { HarmonicHandlerComponent } from './gallery-handler/harmonic-handler/harmonic-handler.component';
import { GravityHandlerComponent } from './gallery-handler/gravity-handler/gravity-handler.component';
import { ImageHandlerComponent } from './gallery-handler/image-handler/image-handler.component';


@NgModule({
declarations: [GalleryHomeComponent, GalleryDetailComponent],
declarations: [
GalleryHomeComponent,
GalleryDetailComponent,
HarmonicHandlerComponent,
GravityHandlerComponent,
ImageHandlerComponent
],
imports: [
CommonModule,
GalleryRoutingModule,
MatCardModule,
MatButtonModule
MatButtonModule,
MatSlideToggleModule,
FormsModule,
MatRadioModule
]
})
export class GalleryModule { }
35 changes: 26 additions & 9 deletions src/services/particle-harmonic.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { Injectable } from '@angular/core';
import P5 from "p5";
import {_P5Particle, ParticleService} from "./particle.service";

export type HarmonicParticleStyle = 'circle' | 'rect';

class HarmonicParticle implements _P5Particle {
p5: P5;
pos: P5.Vector;
Expand All @@ -10,9 +12,10 @@ class HarmonicParticle implements _P5Particle {
d: number;
angle: number;
angleV = 0;
particleStyle: HarmonicParticleStyle = 'circle';

//multi waves
isCombined = false;
isComposite = false;
pos2: P5.Vector;

get crest(): number {
Expand Down Expand Up @@ -46,12 +49,21 @@ class HarmonicParticle implements _P5Particle {
}

render() {
if (this.isCombined) {
if (this.isComposite) {
const sumY = this.p5.map(this.pos.y + this.pos2.y, this.trough + this.trough2, this.crest + this.crest2, this.p5.height * 0.2, this.p5.height * 0.8);
this.p5.circle(this.pos.x, sumY, this.d);
if (this.particleStyle === 'circle') {
this.p5.circle(this.pos.x, sumY, this.d);
} else {
this.p5.rect(this.pos.x - this.d / 2, sumY - this.d / 2, this.d, this.d);
}
} else {
this.p5.circle(this.pos.x, this.pos.y, this.d);
this.p5.circle(this.pos2.x, this.pos2.y, this.d);
if (this.particleStyle === 'circle') {
this.p5.circle(this.pos.x, this.pos.y, this.d);
this.p5.circle(this.pos2.x, this.pos2.y, this.d);
} else {
this.p5.rect(this.pos.x - this.d / 2, this.pos.y - this.d / 2, this.d, this.d);
this.p5.rect(this.pos2.x - this.d / 2, this.pos2.y - this.d / 2, this.d, this.d);
}
}
}
}
Expand All @@ -74,14 +86,11 @@ export class ParticleHarmonicService extends ParticleService {

const sketch = (p5: P5) => {
p5.setup = () => {
const renderer = p5.createCanvas(w, h, canvasEl);
p5.createCanvas(w, h, canvasEl);
p5.background(0, 0, 0);
this.genAngles();
this.genParticles(p5);
this.setupParticles(p5);
renderer.mouseClicked(() => {
this.particles.forEach(p => p.isCombined = !p.isCombined)
})
}
p5.draw = () => this.draw(p5);
}
Expand Down Expand Up @@ -119,4 +128,12 @@ export class ParticleHarmonicService extends ParticleService {
// render
this.particles.forEach(particle => particle.render());
}

toggleComposite() {
this.particles.forEach(p => p.isComposite = !p.isComposite)
}

setParticleStyle(style: HarmonicParticleStyle) {
this.particles.forEach(p => p.particleStyle = style || 'circle')
}
}
2 changes: 1 addition & 1 deletion src/services/particle.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export abstract class _P5Particle {
}

@Injectable({
providedIn: 'root'
providedIn: 'root',
})
export class ParticleService {
context: CanvasRenderingContext2D | null;
Expand Down
9 changes: 9 additions & 0 deletions src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,12 @@ body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
padding: 0;
box-sizing: border-box;
}

.handler-control-row {
margin: 1rem 0;

label {
display: block;
padding-bottom: 2px;
}
}

0 comments on commit b09a49a

Please sign in to comment.