Skip to content

Commit

Permalink
chore(painter): small changes
Browse files Browse the repository at this point in the history
  • Loading branch information
surunzi committed Jan 17, 2024
1 parent 903362b commit aa8765d
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 46 deletions.
53 changes: 33 additions & 20 deletions src/painter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Component, { IComponentOptions } from '../share/Component'
import stripIndent from 'licia/stripIndent'
import $ from 'licia/$'
import each from 'licia/each'
import types from 'licia/types'
import { exportCjs, drag } from '../share/util'
import { Brush, Pencil, Tool } from './tools'

Expand All @@ -28,14 +27,13 @@ export interface IOptions extends IComponentOptions {
export default class Painter extends Component<IOptions> {
private $tools: $.$
private $canvas: $.$
private $viewport: $.$
private canvas: HTMLCanvasElement
private ctx: CanvasRenderingContext2D
private layers: Layer[] = []
private currentTool: Tool
private tools: types.PlainObj<Tool> = {
brush: new Brush(this),
pencil: new Pencil(this),
}
private brush: Brush
private pencil: Pencil
private activeLayer: Layer
constructor(container: HTMLElement, options: IOptions = {}) {
super(container, { compName: 'painter' }, options)
Expand All @@ -50,6 +48,7 @@ export default class Painter extends Component<IOptions> {

this.$tools = this.find('.tools')
this.$canvas = this.find('.main-canvas')
this.$viewport = this.find('.viewport')
this.canvas = this.$canvas.get(0) as HTMLCanvasElement
this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D

Expand All @@ -58,7 +57,10 @@ export default class Painter extends Component<IOptions> {

this.bindEvent()

this.use(this.options.tool)
this.brush = new Brush(this)
this.pencil = new Pencil(this)

this.useTool(this.options.tool)
}
/** Add layer. */
addLayer() {
Expand All @@ -70,16 +72,27 @@ export default class Painter extends Component<IOptions> {
getActiveLayer() {
return this.activeLayer
}
/** Set tool. */
use(name: string) {
/** Use tool. */
useTool(name: string) {
const { c, $tools } = this

if (this.tools[name]) {
this.currentTool = this.tools[name]
const tool = this.getTool(name)

if (tool) {
this.currentTool = tool
$tools.find(c('.tool')).rmClass(c('selected'))
$tools.find(`${c('.tool')}[data-tool="${name}"]`).addClass(c('selected'))
}
}
/** Get tool. */
getTool(name: string) {
switch (name) {
case 'brush':
return this.brush
case 'pencil':
return this.pencil
}
}
getCanvas() {
return this.canvas
}
Expand Down Expand Up @@ -115,28 +128,28 @@ export default class Painter extends Component<IOptions> {
)
}
private bindEvent() {
const { $canvas, $tools, c } = this
const { $viewport, $tools, c } = this

$canvas.on(drag('start'), this.onCanvasDragStart)
$viewport.on(drag('start'), this.onViewportDragStart)

const self = this
$tools.on('click', c('.tool'), function (this: HTMLDivElement) {
const $this = $(this)
self.use($this.data('tool'))
self.useTool($this.data('tool'))
})
}
private onCanvasDragStart = (e: any) => {
private onViewportDragStart = (e: any) => {
this.currentTool.onDragStart(e.origEvent)
$document.on(drag('move'), this.onCanvasDragMove)
$document.on(drag('end'), this.onCanvasDragEnd)
$document.on(drag('move'), this.onViewportDragMove)
$document.on(drag('end'), this.onViewportDragEnd)
}
private onCanvasDragMove = (e: any) => {
private onViewportDragMove = (e: any) => {
this.currentTool.onDragMove(e.origEvent)
}
private onCanvasDragEnd = (e: any) => {
private onViewportDragEnd = (e: any) => {
this.currentTool.onDragEnd(e.origEvent)
$document.off(drag('move'), this.onCanvasDragMove)
$document.off(drag('end'), this.onCanvasDragEnd)
$document.off(drag('move'), this.onViewportDragMove)
$document.off(drag('end'), this.onViewportDragEnd)
}
}

Expand Down
1 change: 1 addition & 0 deletions src/painter/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@

.canvas-container {
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');
font-size: 0;
}

.theme-dark {
Expand Down
56 changes: 30 additions & 26 deletions src/painter/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { eventPage } from '../share/util'

export class Tool {
protected painter: Painter
protected x = 0
protected lastX = 0
protected y = 0
protected lastY = 0
protected x = -1
protected lastX = -1
protected y = -1
protected lastY = -1
protected ctx: CanvasRenderingContext2D
constructor(painter: Painter) {
this.painter = painter
Expand All @@ -32,11 +32,6 @@ export class Tool {
let x = Math.floor(((pageX - offset.left) / offset.width) * canvas.width)

Check failure on line 32 in src/painter/tools.ts

View workflow job for this annotation

GitHub Actions / ci (12.x)

'x' is never reassigned. Use 'const' instead
let y = Math.floor(((pageY - offset.top) / offset.height) * canvas.height)

Check failure on line 33 in src/painter/tools.ts

View workflow job for this annotation

GitHub Actions / ci (12.x)

'y' is never reassigned. Use 'const' instead

if (x < 0 || x > canvas.width || y < 0 || y > canvas.height) {
x = -1
y = -1
}

this.lastX = this.x
this.x = x
this.lastY = this.y
Expand All @@ -57,31 +52,40 @@ export class Pencil extends Tool {
super.onDragMove(e)
const { x, y, lastX, lastY } = this

if (x > -1 && y > -1) {
if (lastX > -1 && lastY > -1) {
const delta = {
x: x - lastX,
y: y - lastY,
}
if (Math.abs(delta.x) > 1 || Math.abs(delta.y) > 1) {
const steps = Math.max(Math.abs(delta.x), Math.abs(delta.y))
delta.x /= steps
delta.y /= steps
for (let i = 0; i < steps; i++) {
const x = lastX + Math.round(delta.x * i)
const y = lastY + Math.round(delta.y * i)
this.draw(x, y)
}
}
const delta = {
x: x - lastX,
y: y - lastY,
}
if (Math.abs(delta.x) > 1 || Math.abs(delta.y) > 1) {
const steps = Math.max(Math.abs(delta.x), Math.abs(delta.y))
delta.x /= steps
delta.y /= steps
for (let i = 0; i < steps; i++) {
const x = lastX + Math.round(delta.x * i)
const y = lastY + Math.round(delta.y * i)
this.draw(x, y)
}
this.draw(this.x, this.y)
}

this.draw(this.x, this.y)
}
draw(x: number, y: number) {
const canvas = this.painter.getCanvas()

if (x < 0 || x > canvas.width || y < 0 || y > canvas.height) {
return
}

const { ctx } = this
const { size } = this.options
ctx.fillStyle = 'black'
ctx.fillRect(x, y, size, size)
this.painter.updateCanvas()
}
}

export class Hand extends Tool {
onDragMove(e: any) {
super.onDragMove(e)
}
}

0 comments on commit aa8765d

Please sign in to comment.