Guten Tag, Freunde!Vorwort
Sobald Web - Surfen fĂŒhrte mich zu diesem .SpĂ€ter entdeckte ich einen Artikel darĂŒber, wie das funktioniert.Es scheint nichts Besonderes zu sein - Pikachu, gezeichnet mit CSS. Diese Technik nennt man Pixel Art (Pixel Art?). Was mich beeindruckt hat, war die KomplexitĂ€t des Prozesses. Jede Zelle wird von Hand bemalt (na ja, fast; da es PrĂ€prozessoren gibt; in diesem Fall Sass). Schönheit erfordert natĂŒrlich Opfer. Der Entwickler ist jedoch eine faule Kreatur. Deshalb habe ich ĂŒber Automatisierung nachgedacht. Also erschien das, was ich Pixel Art Maker nannte.Bedingungen
Was wollen wir bekommen?Wir brauchen ein Programm, das eine bestimmte Anzahl von Zellen mit der Möglichkeit erzeugt, sie mit beliebigen Farben zu fÀrben.Hier einige Beispiele aus dem Internet:ZusÀtzliche Funktionen:- Zellform - Quadrat oder Kreis
- Zellenbreite in Pixel
- Anzahl der Zellen
- Hintergrundfarbe
- Farbe zum FĂ€rben
- Canvas-Erstellungsfunktion
- Funktion zur Anzeige der Zellennummer
- Bildspeicher- / Löschfunktion
- Leinwandreinigungsfunktion
- Leinwandentfernungsfunktion
Wir werden kleinere Details im Codierungsprozess diskutieren.So lass uns gehen.Markup
Um die erforderliche FunktionalitĂ€t zu implementieren, sollte unser HTML ungefĂ€hr so ââaussehen:
<div class="tools">
<div>
<p>Shape Form</p>
<select>
<option value="squares">Square</option>
<option value="circles">Circle</option>
</select>
</div>
<div class="numbers">
<div>
<p>Shape Width <br> <span>(from 10 to 50)</span></p>
<input type="number" value="20" class="shapeWidth">
</div>
<div>
<p>Shape Number <br> <span>(from 10 to 50)</span></p>
<input type="number" value="30" class="shapeNumber">
</div>
</div>
<div class="colors">
<div>
<p>Background Color</p>
<input type="color" value="#ffff00" required class="backColor">
</div>
<div>
<p>Shape Color</p>
<input type="color" value="#0000ff" class="shapeColor">
</div>
</div>
<div class="buttons">
<input type="button" value="Generate Canvas" class="generate">
<input type="button" value="Show/Hide Numbers" class="show">
<input type="button" value="Save/Delete Image" class="save">
<input type="button" value="Clear Canvas" class="clear">
<input type="button" value="Delete Canvas" class="delete">
</div>
</div>
<canvas></canvas>
Der Wertebereich (Grenzwert) fĂŒr die Breite und Anzahl der Zellen wurde empirisch bestimmt. Die Experimente zeigten, dass kleinere / gröĂere Werte aus GrĂŒnden ĂŒbermĂ€Ăiger Detailgenauigkeit (fĂŒr Werte <10 fĂŒr die Breite), verminderter Leistung (fĂŒr Werte> 50 fĂŒr die Menge) usw. unpraktisch sind.Stile
Wir haben nichts Besonderes in Stilen.CSS:* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
margin: 0;
min-height: 100vh;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
align-content: flex-start;
}
h1 {
width: 100%;
text-align: center;
font-size: 2.4em;
color: #222;
}
.tools {
height: 100%;
display: inherit;
flex-direction: column;
margin: 0;
font-size: 1.1em;
}
.buttons {
display: inherit;
flex-direction: column;
align-items: center;
}
div {
margin: .25em;
text-align: center;
}
p {
margin: .25em 0;
user-select: none;
}
select {
padding: .25em .5em;
font-size: .8em;
}
input,
select {
outline: none;
cursor: pointer;
}
input[type="number"] {
width: 30%;
padding: .25em 0;
text-align: center;
font-size: .8em;
}
input[type="color"] {
width: 30px;
height: 30px;
}
.buttons input {
width: 80%;
padding: .5em;
margin-bottom: .5em;
font-size: .8em;
}
.examples {
position: absolute;
top: 0;
right: 0;
}
a {
display: block;
}
span {
font-size: .8em;
}
canvas {
display: none;
margin: 1em;
cursor: pointer;
box-shadow: 0 0 1px #222;
}
Javascript
Definieren Sie die Leinwand und ihren Kontext (2D-Zeichnungskontext):let c = document.querySelector('canvas'),
$ = c.getContext('2d')
Wir finden die SchaltflÀche zum Erstellen der ZeichenflÀche und hÀngen den Click-Event-Handler daran:document.querySelector('.generate').onclick = generateCanvas
Der gesamte weitere Code befindet sich in der Funktion generateCanvas:function generateCanvas(){
...
}
Wir bestimmen die Form, Breite, horizontale Menge und Gesamtmenge (die Leinwand reprÀsentiert die gleiche Anzahl von Zellen horizontal und vertikal) sowie die Hintergrundfarbe:
let shapeForm = document.querySelector('select').value
let shapeWidth = parseInt(document.querySelector('.shapeWidth').value)
let shapeNumber = parseInt(document.querySelector('.shapeNumber').value)
let shapeAmount = Math.pow(shapeNumber, 2)
let backColor = document.querySelector('.backColor').value
Wir bestimmen die GröĂe der Leinwand und legen die entsprechenden Attribute dafĂŒr fest (denken Sie daran, dass die richtige LeinwandgröĂe ĂŒber die Attribute festgelegt wird):
let W = H = shapeWidth * shapeNumber
c.setAttribute('width', W)
c.setAttribute('height', H)
Einige zusÀtzliche Einstellungen:
let border = 1
let borderColor = 'rgba(0,0,0,.4)'
let isShown = false
if (shapeWidth < 10 || shapeWidth > 50 || shapeNumber < 10 || shapeNumber > 50 || isNaN(shapeWidth) || isNaN(shapeNumber)) {
throw new Error(alert('wrong number'))
} else if (shapeForm == 'squares') {
c.style.display = 'block'
squares()
} else {
c.style.display = 'block'
circles()
}
So sieht die Quadratfunktion aus:function squares() {
let x = y = 0
let squares = []
let w = h = shapeWidth
addSquares()
function Square(x, y) {
this.x = x
this.y = y
this.color = backColor
this.isSelected = false
}
function addSquares() {
for (let i = 0; i < shapeAmount; i++) {
let square = new Square(x, y)
x += w
if (x == W) {
y += h
x = 0
}
squares.push(square)
}
drawSquares()
}
function drawSquares() {
$.clearRect(0, 0, W, H)
for (let i = 0; i < squares.length; i++) {
let square = squares[i]
$.beginPath()
$.rect(square.x, square.y, w, h)
$.fillStyle = square.color
$.lineWidth = border
$.strokeStyle = borderColor
$.fill()
$.stroke()
if (isShown) {
$.beginPath()
$.font = '8pt Calibri'
$.fillStyle = 'rgba(0,0,0,.6)'
$.fillText(i + 1, square.x, (square.y + 8))
}
}
}
c.onclick = select
function select(e) {
let clickX = e.pageX - c.offsetLeft,
clickY = e.pageY - c.offsetTop
for (let i = 0; i < squares.length; i++) {
let square = squares[i]
if (clickX > square.x && clickX < (square.x + w) && clickY > square.y && clickY < (square.y + h)) {
if (square.isSelected == false) {
square.isSelected = true
square.color = document.querySelector('.shapeColor').value
} else {
square.isSelected = false
square.color = backColor
}
drawSquares()
}
}
}
document.querySelector('.show').onclick = showNumbers
function showNumbers() {
if (!isShown) {
isShown = true
for (let i = 0; i < squares.length; i++) {
let square = squares[i]
$.beginPath()
$.font = '8pt Calibri'
$.fillStyle = 'rgba(0,0,0,.6)'
$.fillText(i + 1, square.x, (square.y + 8))
}
} else {
isShown = false
}
drawSquares()
}
}
Die Kreisfunktion ist der Quadratfunktion sehr Àhnlich.JavaScript:function circles() {
let r = shapeWidth / 2
let x = y = r
let circles = []
addCircles()
function Circle(x, y) {
this.x = x
this.y = y
this.color = backColor
this.isSelected = false
}
function addCircles() {
for (let i = 0; i < shapeAmount; i++) {
let circle = new Circle(x, y)
x += shapeWidth
if (x == W + r) {
y += shapeWidth
x = r
}
circles.push(circle)
}
drawCircles()
}
function drawCircles() {
$.clearRect(0, 0, W, H)
for (let i = 0; i < circles.length; i++) {
let circle = circles[i]
$.beginPath()
$.arc(circle.x, circle.y, r, 0, Math.PI * 2)
$.fillStyle = circle.color
$.strokeStyle = borderColor
$.lineWidth = border
$.fill()
$.stroke()
if (isShown) {
$.beginPath()
$.font = '8pt Calibri'
$.fillStyle = 'rgba(0,0,0,.6)'
$.fillText(i + 1, (circle.x - 8), circle.y)
}
}
}
c.onclick = select
function select(e) {
let clickX = e.pageX - c.offsetLeft,
clickY = e.pageY - c.offsetTop
for (let i = 0; i < circles.length; i++) {
let circle = circles[i]
let distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2))
if (distanceFromCenter <= r) {
if (circle.isSelected == false) {
circle.isSelected = true
circle.color = document.querySelector('.shapeColor').value
} else {
circle.isSelected = false
circle.color = backColor
}
drawCircles()
}
}
}
document.querySelector('.show').onclick = showNumbers
function showNumbers() {
if (!isShown) {
isShown = true
for (let i = 0; i < circles.length; i++) {
let circle = circles[i]
$.beginPath()
$.font = '8pt Calibri'
$.fillStyle = 'rgba(0,0,0,.6)'
$.fillText(i + 1, (circle.x - 8), circle.y)
}
} else {
isShown = false
}
drawCircles()
}
}
Wir finden die SchaltflÀche zum Speichern / Löschen des Ergebnisses (Bild) und hÀngen den Click-Event-Handler daran:document.querySelector('.save').onclick = () => {
let img = document.querySelector('img')
img == null ? document.body.appendChild(document.createElement('img')).src = c.toDataURL() : document.body.removeChild(img)
}
Wir finden den Knopf zum Reinigen der Leinwand und ...:document.querySelector('.clear').onclick = () => {
$.clearRect(0, 0, W, H)
generateCanvas()
}
Suchen Sie die SchaltflÀche zum Löschen der Leinwand und ...:document.querySelector('.delete').onclick = () => {
$.clearRect(0, 0, W, H)
c.style.display = 'none'
}
Das Ergebnis sieht folgendermaĂen aus:
Codepen (einige AnwendungsfĂ€lle hinzugefĂŒgt)GithubVielen Dank fĂŒr Ihre Aufmerksamkeit.