يوم جيد يا اصدقاء!مقدمة
مرة واحدة قادني تصفح الويب إلى هذا .في وقت لاحق اكتشفت مقالة حول كيفية عمل ذلك.لا يبدو أن هناك شيئًا مميزًا - بيكاتشو ، تم رسمه باستخدام CSS. تسمى هذه التقنية Pixel Art (فن البكسل؟). ما أدهشني هو تعقيد العملية. يتم رسم كل خلية يدويًا (حسنًا ، تقريبًا ؛ نظرًا لوجود معالجات مسبقة ؛ ساس في هذه الحالة). بالطبع الجمال يتطلب التضحية. ومع ذلك ، المطور هو مخلوق كسول. لذلك ، فكرت في الأتمتة. لذا ظهر ما أسميه Pixel Art Maker.الظروف
ما الذي نريد الحصول عليه؟نحن بحاجة إلى برنامج يولد عددًا معينًا من الخلايا مع إمكانية تلوينها بألوان عشوائية.إليك بعض الأمثلة من الويب:وظائف اضافيه:- شكل الخلية - مربع أو دائرة
- عرض الخلية بالبكسل
- عدد الخلايا
- لون الخلفية
- اللون للتلوين
- وظيفة إنشاء قماش
- وظيفة عرض رقم الخلية
- وظيفة حفظ / حذف الصورة
- وظيفة تنظيف قماش
- وظيفة إزالة قماش
سنناقش تفاصيل أصغر في عملية الترميز.إذن هيا بنا نذهب.وضع علامة على
لتنفيذ الوظائف الضرورية ، يجب أن يبدو HTML الخاص بنا على النحو التالي:
<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>
تم تحديد نطاق (حد) القيم للعرض وعدد الخلايا تجريبيا. أظهرت التجارب أن القيم الأصغر / الأكبر غير عملية لأسباب التفصيل المفرط (للقيم <10 للعرض) ، وانخفاض الأداء (للقيم> 50 للكمية) ، إلخ.الأنماط
ليس لدينا شيء خاص في الأنماط.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;
}
جافا سكريبت
تحديد اللوحة وسياقها (سياق الرسم ثنائي الأبعاد):let c = document.querySelector('canvas'),
$ = c.getContext('2d')
نجد زر إنشاء اللوحة القماشية ونعلق معالج حدث النقر عليها:document.querySelector('.generate').onclick = generateCanvas
كل الكود الإضافي سيكون في وظيفة generCanvas:function generateCanvas(){
...
}
نحدد الشكل والعرض والمبلغ الأفقي والمبلغ الإجمالي (تمثل اللوحة نفس عدد الخلايا أفقيًا وعموديًا) ، بالإضافة إلى لون الخلفية:
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
نحدد حجم اللوحة ونحدد السمات المناسبة لها (تذكر أن حجم اللوحة صحيحًا يتم تعيينه من خلال السمات):
let W = H = shapeWidth * shapeNumber
c.setAttribute('width', W)
c.setAttribute('height', H)
بعض الإعدادات الإضافية:
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()
}
إليك ما تبدو عليه دالة المربعات: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()
}
}
دالة الدوائر مشابهة جدًا لوظيفة المربعات.جافا سكريبت: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()
}
}
نجد زر حفظ / حذف النتيجة (الصورة) وتعليق معالج حدث النقر عليه:document.querySelector('.save').onclick = () => {
let img = document.querySelector('img')
img == null ? document.body.appendChild(document.createElement('img')).src = c.toDataURL() : document.body.removeChild(img)
}
نجد زر لتنظيف القماش و ...:document.querySelector('.clear').onclick = () => {
$.clearRect(0, 0, W, H)
generateCanvas()
}
ابحث عن الزر لحذف اللوحة و ...:document.querySelector('.delete').onclick = () => {
$.clearRect(0, 0, W, H)
c.style.display = 'none'
}
تبدو النتيجة كما يلي:
Codepen (تمت إضافة بضعة أمثلة)Githubشكرًا لك على اهتمامك .