Skip to content

Commit

Permalink
add grid and random nails positions
Browse files Browse the repository at this point in the history
  • Loading branch information
dronperminov committed Jun 23, 2022
1 parent 830772c commit 19f3884
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 7 deletions.
10 changes: 10 additions & 0 deletions StringArtGenerator.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ <h1>Генератор изображений в стиле String art</h1>
<div class="range-label" id="brightness-value">0</div>
</div>

<div class="control-block no-top-padding">
<label><b>Расположение гвоздей</b>
<select id="nails-mode-box" disabled>
<option value="border" selected>на границе</option>
<option value="grid">в виде сетки</option>
<option value="random">случайно</option>
</select>
</label>
</div>

<div class="control-block no-top-padding">
<label><b>Количество гвоздей</b><br>
<input type="number" id="nails-count-box" value="250" min="50" max="1000" disabled>
Expand Down
6 changes: 5 additions & 1 deletion js/constants.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const NAIL_RADIUS = 2
const NAIL_RADIUS = 1

const BACKGROUND_COLOR = '#fff'
const BORDER_COLOR = '#000'
Expand All @@ -13,4 +13,8 @@ const ALBUM_FORM = 'album'
const PORTRAIT_FORM = 'portrait'
const IMAGE_FORM = 'image'

const BORDER_MODE = 'border'
const GRID_MODE = 'grid'
const RANDOM_MODE = 'random'

const SCALES = [0.1, 0.25, 0.5, 0.75, 1, 1.25, 1.5, 2, 2.5, 3, 4, 5, 10, 25]
96 changes: 90 additions & 6 deletions js/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ StringArtGenerator.prototype.InitControls = function() {
this.brightnessBox.addEventListener('input', () => this.UpdateBrightness())
this.brightnessBox.addEventListener('change', () => { this.UpdateBrightness(); this.DrawLoadedImage() })

this.nailsModeBox = document.getElementById('nails-mode-box')
this.nailsModeBox.addEventListener('change', () => this.InitArt())

this.nailsCountBox = document.getElementById('nails-count-box')
this.nailsCountBox.addEventListener('change', () => this.InitArt())

Expand Down Expand Up @@ -89,6 +92,7 @@ StringArtGenerator.prototype.InitControls = function() {
this.contrastBox,
this.brightnessBox,
this.formTypeBox,
this.nailsModeBox,
this.nailsCountBox,
this.linesCountBox,
this.linesWeightBox,
Expand Down Expand Up @@ -166,11 +170,9 @@ StringArtGenerator.prototype.GetRectNail = function(angle, x0, y0, width, height
return {x: x, y: y}
}

StringArtGenerator.prototype.InitNails = function() {
this.nails = []

let nailsCount = +this.nailsCountBox.value
StringArtGenerator.prototype.InitBorderNails = function(nailsCount) {
let angle = 2 * Math.PI / nailsCount
let nails = []

for (let i = 0; i < nailsCount; i++) {
let nail = {x: 0, y: 0}
Expand Down Expand Up @@ -199,7 +201,89 @@ StringArtGenerator.prototype.InitNails = function() {
nail.x = Math.round(nail.x)
nail.y = Math.round(nail.y)

this.nails.push(nail)
nails.push(nail)
}

return nails
}

StringArtGenerator.prototype.InitGridNails = function(nailsCount) {
let nails = []
let width = this.imgBbox.xmax - this.imgBbox.xmin
let height = this.imgBbox.ymax - this.imgBbox.ymin
let aspectRatio = width / height


let scale = this.formType == CIRCLE_FORM ? 2 / Math.sqrt(Math.PI) : 1
let wc = Math.round(Math.sqrt(nailsCount * aspectRatio * scale))
let hc = Math.round(Math.sqrt(nailsCount / aspectRatio * scale) * scale)

let x0 = (this.imgBbox.xmin + this.imgBbox.xmax) / 2
let y0 = (this.imgBbox.ymin + this.imgBbox.ymax) / 2

for (let i = 0; i < hc; i++) {
for (let j = 0; j < wc; j++) {
let x = this.Interpolate(this.imgBbox.xmin + PADDING, this.imgBbox.xmax - PADDING, j / (wc - 1))
let y = this.Interpolate(this.imgBbox.ymin + PADDING, this.imgBbox.ymax - PADDING, i / (hc - 1))

if (this.formType == CIRCLE_FORM) {
let dx = x - x0
let dy = y - y0

if (dx * dx + dy * dy > this.radius * this.radius)
continue
}

nails.push({
x: Math.round(x),
y: Math.round(y)
})
}
}

return nails
}

StringArtGenerator.prototype.InitGridRandom = function(nailsCount) {
let nails = []

for (let i = 0; i < nailsCount; i++) {
let x, y

if (this.formType == CIRCLE_FORM) {
let t = Math.random() * 2 * Math.PI
let radius = this.radius * Math.sqrt(Math.random())

x = (this.imgBbox.xmin + this.imgBbox.xmax) / 2 + radius * Math.cos(t)
y = (this.imgBbox.ymin + this.imgBbox.ymax) / 2 + radius * Math.sin(t)
}
else {
x = this.imgBbox.xmin + Math.random() * (this.imgBbox.xmax - this.imgBbox.xmin)
y = this.imgBbox.ymin + Math.random() * (this.imgBbox.ymax - this.imgBbox.ymin)
}

nails.push({
x: Math.round(x),
y: Math.round(y)
})
}

return nails
}

StringArtGenerator.prototype.InitNails = function() {
let nailsMode =this.nailsModeBox.value
let nailsCount = +this.nailsCountBox.value
this.nails = []

if (nailsMode == BORDER_MODE) {
this.nails = this.InitBorderNails(nailsCount)
}
else if (nailsMode == GRID_MODE) {
this.nails = this.InitGridNails(nailsCount)
}
else if (nailsMode == RANDOM_MODE) {
this.nails = this.InitGridRandom(nailsCount)
}
}

Expand Down Expand Up @@ -240,7 +324,7 @@ StringArtGenerator.prototype.InitLinesAnimation = function(nail) {
return
}

this.statusBox.innerHTML = `Инициализация линий (${nail + 1} / ${this.nails.length})`
this.statusBox.innerHTML = `Инициализация линий (${((nail + 1) / this.nails.length * 100).toFixed(2)}%)`
this.generateBtn.setAttribute('disabled', '')

for (let i = 0; i < nail; i++) {
Expand Down

0 comments on commit 19f3884

Please sign in to comment.