I den här handledningen tar vi den mekaniska ritningen Toy Etch en skiss som en inspiration och försök att genomföra dessa funktioner för moderna enheter, med webbteknik. Med hjälp av den (aptly het) duk, fokuserar vi först på tabletter, som är likadana i den autentiska leksaken. Vi kan utnyttja beröringshändelser för att styra uppringningarna och enhetens rörelsehändelser för att radera innehållet. Inte lämnar telefoner, vi kommer också att utforska hur man använder Websockets för att förbättra möjligheterna genom att dela upp kontrollerna och ritningsområdet.
Denna handledning kommer att använda node.js. Innan vi börjar, gå till Filerilo , välj Gratis grejer och gratis innehåll bredvid handledningen - här kan du hämta de tillgångar du behöver för handledningen. Kör sedan kommandona nedan, som installerar beroenden och lanserar servern. Vi använder nod för att skapa en lokal värd , och det kommer också att tjäna oss senare för Websockets.
npm installera
nodserver / index.js
I main.js , den dra() funktionen kommer att vara centrumpunkten för vår ansökan. Vi använder duk för att rita en linje mellan två punkter; Ursprunget (X1, Y1), där vi senast lämnade vår ritning och destinationen (X2, Y2), den nya punkten vi vill nå. Vi behöver nu utlösa den här funktionen för att observera någon form av ritning.
Funktionsdrag (X1, Y1, X2, Y2) {
// Kontext är att sättas globalt i init ()
context.beginpath ();
sammanhang.Moveto (x1, y1);
context.lineto (x2, y2);
sammanhang.stroke ();
}
Innan vi implementerar ringer, låt oss snabbt lägga till en tangentbordslistare som kan utlösa vår dragfunktion. Du har redan fått de olika keycodes i exemplet, men du måste ändra lyssnaren något för att utlösa dra() Funktion som vi definierade tidigare. Uppdatera nu din webbläsare och se vad du kan rita med piltangenterna.
document.addeventlistener ('Keydown', funktion (e) {
/ * Keycode-omkopplaren går här * /
Draw (Math.floor (Prev_Horizontal), Math. Flor (Prev_Vertical), Math. Floor (Horisontell), Math. Floor (vertikal));
prev_vertical = vertikal;
prev_horizontal = horisontell;
});
Du kanske har märkt att vårt canvaselement inte har en storlek tilldelad den än. För vår ritbord vill vi ha ett större utrymme, kanske även hela fönstret. Koden nedan tar hand om resize-evenemanget, men glöm inte att ringa JusteraFrame () i i det() också.
Funktion JusteraFrame () {
// Canvas definieras globalt i init ()
canvas.width = window.innerwidth;
canvas.height = window.innerheight;
}
Window.Addeventlistener ('Ändra storlek, JusteraFrame);
Vi vill att applikationen ska se ut som den ursprungliga leksaken så mycket som möjligt, så vi vill lägga till en ram runt ritningsområdet. För att göra det kan vi definiera ett marginalvärde och ändra CSS för #skiss till marginal: 20px auto; Att centrera duken horisontellt och håll ett större utrymme längst ner för ratten.
VAR framemarginvertical = 122;
varramemarginhorizontal = 62;
Funktion JusteraFrame () {
canvas.width = window.innerwidth - framemarginhorizontal;
canvas.height = window.innerheight - framemarginvertical;
}
Vi har redan gett dig CSS för ratterna i Public / CSS / Styles.CSS , så var god att ta en titt. Lägg sedan till två & lt; div & gt; Taggar under & lt; Canvas & GT; i HTML-filen, som beskrivs nedan. Som en konvention använder vi den vänstra ratten för horisontell ritning och höger för vertikal. Vi lägger också till nya variabler till i det() funktion för att förbereda sig för beröringshändelser.
& lt; div id = "dialhorizontal" class = "dial" & gt; & lt; / div & gt;
& lt; div id = "dialogvertical" class = "dial" & gt; & lt; / div & gt;
VAR TILLETELEFT = DOCUMENT.GETELEMENTBYID ('DIALHORIZONTAL');
Var RegionLeft = Ny ZingTouch.region (TargetLeft);
Var TargetRight = document.getElementByD ('dialvertical');
Var RegionRight = Ny ZingTouch.region (TargetRight);
ZingTouch är ett JavaScript-bibliotek som kan upptäcka olika touch-gester, och hanterar också mushändelser. Det är försett för dig i / Public / Lib / Mapp, som vi använder den för att styra våra rattar. Nedan följer genomförandet för vänster kontroll; Du måste replikera och ändra den för den andra sidan.
RegionLeft.Bind (TargetLeft, "Rotate", Funktion (E) {
om (e.detail.distancefromlast & lt; 0) {
--horisontell;
} annars {
++ horisontellt;
}
angleSizontal + = e.detail.distancefromlast;
TargetLeft.Style.Transform = 'Rotera (' + ANGNEHORIZONTAL + 'DEG)';
Rita (Math.floor (Prev_Horizontal), Math. Floor (Prev_Vertical), Math. Floor (Horisontell), Math. Floor (Prev_Vertical));
prev_horizontal = horisontell;
});
För att blockera linjerna från att gå på skärmen använder vi Candraw () funktion, som returnerar en booleska. Vi passerar det riktningen, antingen "horisontell" eller "vertikal" och värdet av antingen den horisontella eller vertikala variabeln. Vi kallar den här funktionen i lyssnaren "Rotate" av båda ringarna, och endast om "sant" ökar vi vinkeln och ringer dra() fungera.
Funktion Kandrot (riktning, värde) {
var max = (riktning === 'horisontell')? (canvas.width) :( canvas.height);
om (värde & lt; 2 || värde och gt; max - 2) {
returnera false;
}
returnera sant;
}
Med de gränser vi just har implementerat finns det en chans att ratten kan fastna i ena änden om värdet går över gränsen, även med en decimalpunkt. För att undvika denna situation, bör vi hantera fallet där Candraw () är falskt och återställ värdet till en tidigare giltig, som visas här för den horisontella styrenheten:
Om (Kandrot ("Horisontell", Horisontell)) {
angleSizontal + = e.detail.distancefromlast;
TargetLeft.Style.Transform = 'Rotera (' + ANGNEHORIZONTAL + 'DEG)';
Rita (Math.floor (Prev_Horizontal), Math. Floor (Prev_Vertical), Math. Floor (Horisontell), Math. Floor (Prev_Vertical));
prev_horizontal = horisontell;
} annars {
horisontell = prev_horizontal;
}
Det rekommenderas alltid att testa på dina riktade enheter så tidigt som möjligt. Vår ansökan är nu i bra form och kan svara på beröringshändelser. Följ stegen om att komma åt Localhost på distans för att få ritbordet på din surfplatta.
Därefter använder vi Safari och utvecklingsmenyn för att inspektera programmet på en iPad. För Android-enheter, använd Chrome: // inspektera .
Anslut din surfplatta till datorn via USB och inspektera programmet med hjälp av verktygsverktygen.
Med koden nedan på plats bör du kunna se de olika accelerationsvärdena, när du flyttar enheten runt. För att återställa duken har vi bestämt oss för att överväga en acceleration på X-axeln över 5 och sakta minska opaciteten ( radera ).
Var Eraserat = 1; / * definiera som en global variabel * /
Window.Addeventlistener ('Devicemotion', Function (Event) {
Console.log ('Acceleration ::', evenemang.acceleration);
om (evenemang.acceleration.x & gt; 5) {
Eraserat - = Math.abs (Event.Acceleration.x / 100);
Console.log ("Radera ::", radera);
}
});
Vi har sett i föregående steg hur man kontrollerar för rörelse och acceleration. Vi behöver nu ringa Fadedrawing () när vårt tillstånd är uppfyllt. I det här fallet redrawerar vi en exakt kopia av duken på en annan opacitet.
Återställ globalalpha till 1 in dra() och sätt in globalcompositeoperation Tillbaka till källan.
Funktion Fadedrawing () {
Om (Eraserat & LT; 0) {
context.ClearRect (0, 0, canvas.width, canvas.height);
Eraserat = 1;
lämna tillbaka;
}
Context.GlobalalPha = Eraserat;
Context.GlobalCompositeOpperation = 'Copy';
context.drawimage (canvas, 0, 0);
}
Hittills ser vår ansökan ganska snygg och platt. För att ge det lite djup lägger vi till en ramfärg, en skugga inuti ramen och lite volym på ratten. CSS för dialskuggorna är redan anordnade, men du måste lägga till de två elementen i slutet av kroppen.
Slutför CSS för de föreslagna elementen här:
& lt; div id = "dialshadowhorizontal" klass = "skugga" & gt; & lt; / div & gt;
& lt; div id = "dialshadowvertical" class = "shadow" & gt; & lt; / div & gt;
kropp {
Bakgrund: # 09cbf7;
}
#skiss {
Box-Shadow: 2px 2px 10px rgba (0, 0, 0, .25) insats;
}
I början av den här handledningen nämnde vi kort med Websockets via vår nodserver. Nu när du har en fristående ritningsplatta för tablett, kommer vi också att titta på att du gör det tillgängligt för din telefon. Telefoner kan dock vara för små för att visa både skärmen och kontrollerna. Vi använder därför socklar för att kommunicera mellan telefon och datorskärm.
I huvud HTML-filen, byt ut main.js med extra.js . Den senare innehåller allt vi har gjort hittills, med ändringar för att hantera enheter och uttag, som vi inspekterar i följande steg. Ta en titt på detectdevice () - Denna metod blir nu kallad belastning istället för i det() och kommer att bestämma vilket "läge" att hantera för ansökan.
Nedan är det speciella fallet att en telefon upptäcks:
Om (Window.InnerWidth & LT; 768) {
socket = io.connect ();
document.queryselector ('# skiss'). Ta bort ();
Var Rings = Document.QuerySelectorAll ('. Dial, .shadow');
[] .foreach.call (ringer, funktion (artikel) {
objekt.classlist.add ('big');
});
iscontrols = sant;
Framemargyvertical = 62;
socket.emit ('Ready', {'Ready': 'Controls'});
}
Genom hela extra.js Du kommer att märka bitar av kod som socket.emit () eller socket.on () . Det här är emittenterna och lyssnare för våra kontroller (telefon) och skärm (dator). Varje emitterad händelse måste gå igenom servern som ska distribueras till alla anslutna socklar. I server \ index.js Lägg till några fler lyssnare i funktionen "anslutning" och starta om nodservern.
socket.on ('draw', funktion (data) {
io.sockets.emit ("rita", data);
});
socket.on ('Erase', Function (Data) {
io.sockets.emit ("Erase", data);
});
socket.on ('JusteraFrame', funktion (data) {
screenwidth = data.screenwidth;
ScreenHeight = Data.ScreenHeight;
io.sockets.emit ("JusteraFrame", data);
});
Besök localhost på din dator, samtidigt som du öppnar den på distans med din telefon (som du gjorde tidigare från din surfplatta). Du bör nu se en rad som dras på din skärm medan du vrider uppringningarna på din telefon. Du kommer dock att märka att rattarna inte passar ordentligt om telefonen är i stående läge.
Vi kan fixa detta med några CSS:
@media skärm och (orientering: porträtt) {
.dial.big # dialogvertical, .shadow.big # dialshadowvertical {
Höger: Beräkna (50% - 75px);
botten: 20px;
Topp: Auto;
}
.dial.big # dialhorizontal, .shadow.big # dialshadowhorizontal {
Vänster: Beräkna (50% - 75px);
Topp: 20px;
}
}
Låt oss komma tillbaka till vår Tablet-version. Tyvärr är vibration API inte tillgänglig på iOS, så vi kan inte implementera haptisk återkoppling när ratten vrids. I den ursprungliga leksaken kan du dock lämna tillfälliga svarta fingeravtrycksmärken på skärmen om du tryckte den. Vi kan lägga till en pekhändelse på enheten för att replikera den här funktionen.
Ställ in dessa lyssnare i i det() och utforska de funktioner som de kallar:
om (typ === 'all') {
canvas.addeventlistener ('Touchstart', funktion (e) {
E.PreventDefault ();
DrawfingerPrint (E.LayerX, E.Layery, True);
});
canvas.addeventlistener ('touchend', funktion (e) {
HideFingerPrint (E.LayerX, E.Layery);
});
}
I DrawfingerPrint () Metod, innan vi gör något annat, sparar vi en kopia av det aktuella läget för duken till ett dolt element som vi använder för att återställa vår ritning när vi rensar utskriften. Det händer bara vid första handen, och inte på de efterföljande samtalen som ökar utskriftens storlek varje 100ms.
Funktion DrawfingerPrint (XPOS, YPOS, SAVECANVAS) {
/ * Delvis funktion, se Extra.js * /
Om (SaveCanvas) {
HiddenCanvas = document.createelement ('canvas');
VAR HIDDENCONTEXT = HIDDENCANVAS.GETCONTEXT ('2D');
hiddencanvas.width = canvas.bred;
HiddenCanvas.Height = Canvas.Height;
hiddencontext.drawimage (canvas, 0, 0);
}
}
Du kan nu göra ansökan verkligen fristående genom att spara den på din surfplatta som en startskärmsapp. Vi kommer inte att kunna göra detsamma för telefonen, eftersom det kräver anslutning till servern. I /offentlig , hitta filen som heter skiss.appcache och ersätta alla instanser av "localhost" av din IP-adress.
Ändra nu HTML för att läsa enligt följande:
& lt; html lang = "en" manifest = "sketch.appcache" & gt;
Besök nu programmet igen på din surfplatta och välj alternativet Lägg till i hemmet. En ny ikon ska visas på skrivbordet. Öppna det en gång när du fortfarande är ansluten till din localhost på distans. Cache Manifest vi satt upp tidigare hämtar alla nödvändiga filer för offlineanvändning i bakgrunden. Stäng av Wi-Fi och öppna appen igen. Voilà!
Denna artikel uppträdde ursprungligen i Web Designer Magazine Utgåva 263. Köp det här .
Läs mer:
(Bildkredit: Webbdesigner) Att ha ett område som tillåter användare att logga in och ladda ner eller visa dokument..
När man arbetar med projekt som App Design eller Branding Collateral är det viktigt att det finns konsistens mellan olika eleme..
Blir ombedd att beskriva mina målningsteknik är udda för mig, och uppriktigt är det svårt att göra. Jag är ..
Det finns en obefogad mystik runt oljemålning som har lagt några artister från att utforska dem. Om du känner till höger ..
Webgl , som är allmänt stödd på alla moderna webbläsare, gör att du kan arbeta med hårdvaruaccelerat 3D-grafik..
Att måla en figur som ser trovärdigt våt kräver att du tar ett antal faktorer - en nyckel som är den typ av tyg som de har p..
Denna handledning tar en titt på hur du kan göra en flytande stänk eller kronans effekt och kan användas för att göra stän..
I åren blev jag skrämmad genom att arbeta digitalt. Något om plastbenet på en plastyta kände sig för att skada mig. Jag äl..