เช่นเคย แค่ดูภาพ!
ผลกระทบมีดังนี้:
ภาพ HD ขนาดใหญ่!
ฉันทำงานเป็นโค้ดเดอร์มาหลายปีแล้ว แต่ตาของฉันมัวลงและมองเห็นภาพเคลื่อนไหวไม่ชัดเจนใช่ไหม - จากนั้นดูภาพหน้าจอแบบคงที่! - -
ผลกระทบของคะแนนที่แตกต่างกันมีดังนี้:
ชมการแสดงของแม่ค้าแล้วเรามาดูขั้นตอนการผลิตสินค้ากันดีกว่า!
Canvas วาดวงกลม 1 ใน vue โค้ดใน <template lang=pug> เป็นดังนี้:
canvas#baseCanvas คือวงแหวนสีเทาที่ด้านล่าง
canvas#myCanvas คือวงแหวนสีด้านบน
เราจำเป็นต้องใช้สไตล์ CSS เพื่อช่วยเราปกปิดวงแหวนสีที่อยู่ด้านบนของวงแหวนสีเทา
2. สไตล์ CSS: 3. รหัสการวาดสไตล์ js-canvasโค้ดนี้ง่ายมาก เพียงดูที่ canvas api
3-1 ในคอมโพเนนต์ vue ให้กำหนดตัวแปรที่ต้องการที่ด้านบนของแท็กสคริปต์
3-2 ในอ็อบเจ็กต์เมธอดของ vue มีการกำหนดสามวิธี:
DrawBaseCanvas: ใช้ในการวาดวงแหวนสีเทาด้านล่าง เนื่องจากวงกลมสีเทาไม่มีเอฟเฟ็กต์ภาพเคลื่อนไหว เพียงวาดวงกลมสีเทาทั้งหมดที่จุดเริ่มต้น DrawClrCanvas: ใช้ในการวาดวงแหวนสีด้านบน clearCanvas : ใช้ในการเคลียร์ผ้าใบ นี่คือสิ่งที่แอนิเมชั่นวงแหวนสีต้องการ เนื่องจากแก่นแท้ของเอฟเฟกต์วงแหวนของเราคือการล้างวงแหวนสีเป็นระยะ ๆ จากนั้นเพิ่มค่ามุมสิ้นสุดและวาดใหม่ เพื่อให้เป็นแอนิเมชั่นต่อเนื่อง
นี่คือรหัสสำหรับสามวิธี:
รหัสในสามวิธีข้างต้นเป็นแอปพลิเคชันเกือบทั้งหมดของ Canvas API เพียงอ่านบทช่วยสอน
เฉพาะในวิธี draoClrCanvas เมื่อวาดวงกลมผืนผ้าใบ ค่าเริ่มต้นและค่าสิ้นสุดจะถูกตั้งค่าในพารามิเตอร์ส่วนโค้ง
ค่าเริ่มต้นกำหนดตำแหน่งการวาดเริ่มต้นของวงกลม และค่าสุดท้ายกำหนดตำแหน่งสิ้นสุด (เหมือนจะพูดไร้สาระ แต่พอคิดหนักกับข้อความอธิบายความคิดแล้ว ไม่อยากลบเลย 555)
การคำนวณมูลค่าสุดท้ายนี้ค่อนข้างลำบากสำหรับฉัน
เหตุใดจึงต้องคำนวณตัวแปรการนับเช่นนี้ ฉันลืมไปแล้วว่าคิดออกได้อย่างไร
this.grade เป็นจำนวนเต็มบวกภายใน 100 ซึ่งแสดงถึงคะแนน มันถูกกำหนดไว้ในข้อมูล และค่าเริ่มต้นคือ 0 คะแนน
วงกลมสีจึงมองไม่เห็นที่จุดเริ่มต้นเพราะจุดเริ่มต้นและจุดสิ้นสุดเป็น 0 คะแนนทั้งคู่
หากคุณเปลี่ยนค่าของเกรดจาก 0-100 ค่าของวงแหวนสีแคนวาสก็จะเปลี่ยนไปด้วย
ด้วยวิธีนี้ ตราบใดที่เราค่อยๆ แก้ไขค่าของเกรดและวาดใหม่ วงแหวนสีจะค่อยๆ เพิ่มขึ้นเพื่อให้ได้เอฟเฟกต์ภาพเคลื่อนไหว
เอฟเฟ็กต์ภาพเคลื่อนไหวแบบวงแหวนเนื่องจากความต้องการพิเศษของฉันที่นี่ ภาพเคลื่อนไหวจึงต้องถูกทริกเกอร์ทุกครั้งที่ผู้ใช้หันไปที่ตัวปัดซึ่งเป็นที่ตั้งของผืนผ้าใบ (ต่อมาจะยุ่งยากกว่าและต้องใช้ฮิสโตแกรมและส่วนผืนผ้าใบให้มีเอฟเฟกต์ทางเข้าก่อนที่แอนิเมชั่นจะเริ่มต้น) เอฟเฟกต์จะยาวที่สุดในรูปภาพด้านบน (เช่น แอนิเมชัน GIF นั้น)
ดังนั้นฉันต้องใช้รูดเพื่อให้บรรลุผล ในฟังก์ชันเรียกกลับของสวิตช์ปัดนิ้ว คะแนนเกรดจะเพิ่มขึ้นอย่างต่อเนื่องจาก 0 และการวาดวงแหวนสีจะถูกกระตุ้นใหม่เพื่อให้ได้เอฟเฟกต์ภาพเคลื่อนไหว
ตัวปัดที่ฉันใช้ใน vue คือ 'vue-awesome-swiper' ฉันได้เขียนขั้นตอนการใช้งานของเธอไว้ในบทความอื่นแล้ว
มีวัตถุ on ในการกำหนดค่าของ Swiper ใน vue-data ฟังก์ชัน SlideChange ในออบเจ็กต์ on คือฟังก์ชันโทรกลับที่จะถูกทริกเกอร์ทุกครั้งที่รูดเปลี่ยนหน้า
ที่นี่ฉันจะพูดถึงประเด็นพิเศษบางประการ:
(1) vm: เป็นตัวแปรที่ฉันเก็บไว้ในสคริปต์ vue มันถูกเตรียมใช้งานเป็น null จากนั้นเมื่อเมาท์จะถูกกำหนดให้เป็นวัตถุอินสแตนซ์ vue
เริ่มต้นข้อมูลและวาดวงกลมสีเทา
ด้วยวิธีการนี้ ฉันจะได้รับค่าแอตทริบิวต์ grade และ gradeTarget ในฟังก์ชัน vue instance object-data-swiper-callback และแก้ไข
PS: ฉันไม่รู้ว่านี่เป็นแนวทางที่งี่เง่าหรือไม่ เมื่อฉันทำสิ่งนี้ ฉันพบปัญหา ฉันไม่รู้วิธีรับอินสแตนซ์ vue ในการเรียกกลับของ Swiper จึงมีวิธีการกอบกู้ประเทศที่โค้งงอเช่นนี้ หากฉันมีทางออกที่ดีกว่า ฉันหวังว่าคุณจะสามารถให้แนวคิดใหม่แก่ฉันได้ ขอบคุณมากที่รัก
(2) (this.activeIndex == 2 && vm.isStar) ||. (this.activeIndex == 1 && !vm.isStar)
การตัดสินนี้เกิดขึ้นเนื่องจากธุรกิจและสามารถเพิกเฉยได้
ซึ่งชี้ไปที่วัตถุรูดในฟังก์ชันรูดเปลี่ยน this.activeIndex เป็นคุณสมบัติของอินสแตนซ์ของ Swiper ในแง่ทางการจะส่งคืนดัชนีของบล็อกที่ใช้งานอยู่ในปัจจุบัน (บล็อกการเปิดใช้งาน) คุณสามารถเข้าใจได้ว่าเขากำลังอ้างถึงหน้าที่คุณกำลังเปิดอยู่ ซึ่งเป็นตัวห้อยของสไลด์เลื่อนที่คุณกำลังดูอยู่
เนื่องจากตัวตนของฉันในฐานะผู้ใช้ ฉันจะตัดสินใจอย่างเด็ดขาดว่าจะแสดงหน้าก่อนหน้าของตัวปัดซึ่งเป็นที่ตั้งของผืนผ้าใบปัจจุบันหรือไม่ หากไม่ปรากฏขึ้น หน้าก่อนหน้าจะไม่ถูกวาดเลย จากนั้นตัวห้อยรูดที่สอดคล้องกันของหน้าปัจจุบันจะกลายเป็น (ดัชนี-1)
โดยรวมแล้ว เมื่อตรงตามเงื่อนไขและผู้ใช้เปิดไปที่หน้ารูดซึ่งมีผืนผ้าใบอยู่ ฉันจะทริกเกอร์ตรรกะการวาดวงแหวนใน if มิฉะนั้น ไปที่ else เพื่อเริ่มต้นสถานะหน้าข้อมูล ล้างตัวจับเวลาเพื่อหยุดภาพเคลื่อนไหวชั่วคราว และล้างวงแหวนสี
(3)vm.aniShow
ดังที่กล่าวไว้ในบทความล่าสุดของฉัน "การวาดฮิสโตแกรมด้วย Pure CSS" ควรหารือเกี่ยวกับภาพเคลื่อนไหวของฮิสโตแกรมร่วมกับภาพเคลื่อนไหวของผืนผ้าใบ เนื่องจากการนำแอนิเมชั่นไปใช้ต้องร่วมมือกับการสลับสไวเปอร์ นั่นคือรหัสที่นี่:
เมื่อแอตทริบิวต์ vue - data - aniShow เป็นจริง ชื่อคลาส ani จะถูกเพิ่มใน div.row:
ในทำนองเดียวกัน หาก aniShow เป็นจริง ความสูงของความคืบหน้าจะแนบไปกับค่าเป้าหมายของตัวเอง กล่าวคือ ความสูงที่แท้จริงของความคืบหน้าจะถูกกำหนดให้กับความสูงของแอตทริบิวต์สไตล์หลังจากแปลงเป็นเปอร์เซ็นต์
ในขณะนี้ เนื่องจากการเปลี่ยนแปลงความคืบหน้าจะติดตามการเปลี่ยนแปลงความสูง ภาพเคลื่อนไหวที่เพิ่มขึ้นของฮิสโตแกรมพร้อมกับความสูงที่เพิ่มขึ้นจึงเริ่มต้นขึ้น
ภายใต้ชื่อของคลาส ani ความล่าช้าในการเปลี่ยนแปลงของความคืบหน้าทำให้เกิดเอฟเฟกต์ที่เพิ่มขึ้นอย่างมาก
แค่อ่านคำอธิบายข้อความก็อาจทำให้สับสนได้ แต่ลองพิจารณาผลกระทบอีกครั้ง:
(4) ส่วนรหัสการวาดวงกลมสี
gradeTarget คือคะแนนจริง ซึ่งเป็นผลลัพธ์สุดท้ายที่จะดึงออกมา
เกรดเริ่มต้นจาก 0 และเพิ่มเป็นขนาดของ gradeTarget
ฉันไม่ได้ ++vm.grade โดยตรงที่นี่ และตอนนั้นฉันไม่รู้ว่าฉันกำลังคิดอะไรอยู่
หากตัดสิน หากเกรดเพิ่มขึ้นตามค่าเป้าหมาย gradeTarget หรือมากกว่าค่าเป้าหมาย ให้หยุดการเพิ่มและให้ grade=gradeTarget การตัดสินที่เป็นของค่าวิกฤต ในฟังก์ชั่นการเคลื่อนไหวก็ถือเป็นการตรวจจับการชนด้วย
ในทางตรงกันข้าม หากไปไม่ถึงเป้าหมาย ผืนผ้าใบที่วาดครั้งสุดท้ายจะถูกล้าง และวงแหวนสีใหม่จะถูกวาดใหม่หลังจากที่เกรดมีการเปลี่ยนแปลงทีละน้อย
(5) ใส่สิ่งเหล่านี้ทั้งหมดลงใน setTimeout หยุดเป็นเวลา 500 มิลลิวินาทีก่อนที่จะดำเนินการ เพื่อรอให้แผนภูมิแท่งและแผนภูมิวงแหวนเข้าสู่ตลาดก่อนที่จะเริ่มวาดเอฟเฟกต์ที่เพิ่มขึ้นของวงกลม
ที่จริงแล้วโค้ดข้างต้นเป็นกระบวนการทางตรรกะที่ง่ายมาก ผู้อ่านควรจะสามารถเข้าใจได้หลังจากอ่านโค้ดเพียงครั้งเดียว
แนวคิดใหม่:
ฉันสร้างเอฟเฟกต์นี้เมื่อนานมาแล้ว ตอนที่ฉันแยกแยะวิธีการผลิตวันนี้ ฉันคิดถึงโซลูชันการปรับให้เหมาะสมสำหรับโค้ดของฉันเอง:
ที่จริงแล้ว ไม่จำเป็นต้องเรียกวิธีการวาดวงกลมสีอีกครั้งในตัวจับเวลา สิ่งที่เราเปลี่ยนแปลงโดยตรงคือแอตทริบิวต์ this.grade เป็นการดีที่จะติดตามการเปลี่ยนแปลงของแอตทริบิวต์นี้ ด้วยวิธีนี้ เมื่อคุณสมบัตินี้ถูกแก้ไขในตัวจับเวลา วิธีการส่งเสียงจะถูกดำเนินการโดยอัตโนมัติ
นี่ยังคงเป็นแนวคิดและยังต้องการการฝึกฝนของฉัน
เอฟเฟกต์ส่วนเพิ่มของข้อความตรงกลาง:เนื่องจากเกรดเป็นคะแนนที่เพิ่มขึ้นในแต่ละครั้ง คุณสามารถใช้การเชื่อมโยงข้อมูลแบบสองทางของ Vue เพื่อผูกเกรดโดยตรงเป็นค่าคะแนนไปยังมุมมอง DOM ที่สอดคล้องกัน
ในที่สุด ภาพเคลื่อนไหวของวงแหวนและแผนภูมิแท่งด้านบนจะรวมเข้ากับภาพเคลื่อนไหวเพื่อควบคุมความล่าช้าของภาพเคลื่อนไหว ง่ายมาก
ซอร์สโค้ด index.vue:
(หมายเหตุ ซอร์สโค้ดได้รับการจัดระเบียบและแยกออกเล็กน้อย เพื่อความสมบูรณ์และเพื่อปกป้องรหัสธุรกิจอื่น ๆ จึงได้มีการแก้ไขชื่อตัวแปรบางตัวซึ่งอาจแตกต่างจากภาพหน้าจอก่อนหน้าเล็กน้อย)
<เทมเพลต lang='pug'> .indexs#Indexs.app-bg การเปลี่ยนแปลง (ชื่อ = จาง)wiper#swiperBox(:options=swiperOption ref=mySwiper)wiper-slide.swiper-slide1 .container .upรูด-slide.swiper -slide2(v-if=isShow) .my-shark .up wiper-slide.swiper-slide3 .container .data-cont .data.data01 .data01-charts .row(v-for='item,index in Data' :key=index :class='aniShow ? ani:') data-txt {{item.grade > 0 ? item.grade : 'ไม่มีข้อมูล'}} .progress(:class='item.grade == 0 ? nodata : ' :style='height: ' + (aniShow ? (item.grade >= 100 ? (100 * 1.5) / 100 : item.grade == 0 ? 0.04 : item.grade * 1.5 / 100 ) : 0) +'rem') span.pg-data .week {{item.week}} .data.data02 .data02-charts .canvas-box //- baseCanvas canvas#baseCanvas.my-canvas(ref=baseCanvas width=174 height=174) //- canvas canvas#myCanvas.my-canvas.clr-canvas(ref=myCanvas width =174 ความสูง=174) .canvas-data #[span.num {{grade}}]คะแนน</template><script>var vm = null, timer1 = null, /* ค่าพื้นฐาน canvas*/ c = null, //document.getElementById(myCanvas); ctx = null, //canvas-2d canvas x = 161/2 + 1, // พิกัดกึ่งกลางวงกลม r = (161 - 10) / 2; // ขนาดรัศมี/* ส่วนประกอบของรูด * / นำเข้า { รูด, รูดสไลด์ } จาก vue-awesome-swiper; นำเข้า { getData } จาก ../io/getData;export default { ชื่อ: ดัชนี, ส่วนประกอบ: { ปัด, ปัดนิ้ว }, ข้อมูล () { ส่งคืน { เกรด: 0, // แผนภูมิโดนัทคะแนน gradeTarget: 78.54, // หมายเลขคะแนนจริง คุณสามารถแก้ไข isShow: true หลังจากขอข้อมูลผ่าน ajax, // ไม่ว่าจะแสดงรูดหน้าที่สอง aniShow: false, // ไม่ว่าจะเปิดใช้งานภาพเคลื่อนไหวแผนภูมิคอลัมน์ ข้อมูล: [{ สัปดาห์: สัปดาห์แรก เกรด: 0 }, { สัปดาห์: สัปดาห์ที่สอง เกรด: 30 }, { สัปดาห์: สัปดาห์ที่สาม เกรด: 99.99 }, { สัปดาห์: สัปดาห์ที่สี่ เกรด: 76.98 }, { สัปดาห์: สัปดาห์ที่ห้า เกรด: 100 }], SwiperOption: { // พารามิเตอร์ Swiper notNextTick: จริง, ทิศทาง: แนวตั้ง, GrabCursor: จริง, setWrapperSize: จริง, autoHeight: จริง, สไลด์PerView: 1, mousewheel: false, mousewheelControl: false, ความสูง: window.innerHeight, // การตั้งค่าความสูง, เติมความต้านทานความสูงของอุปกรณ์อัตราส่วน: 0, สังเกตผู้ปกครอง: จริง, สไลด์เริ่มต้น: 2 - 1, // เมื่อตั้งค่าการเริ่มต้น หน้าแสดงเริ่มต้นของ Swiper เริ่มต้นจากศูนย์: { slideChange() { if ( (this.activeIndex == 2 && vm.isShow) ||. (this.activeIndex == 1 && !vm.isShow) ) { console.log(this.activeIndex, vm.isShow, วาดภาพเคลื่อนไหว); setTimeout(function() { // แสดงภาพเคลื่อนไหวฮิสโตแกรม vm.aniShow = true; // ตัวจับเวลาจะทริกเกอร์การวาดวงแหวนสีอย่างต่อเนื่องเพื่อให้ได้เอฟเฟกต์ภาพเคลื่อนไหวแบบวงแหวน timer1 = setInterval(function() { // เปลี่ยนการเขียนคำโฆษณาของคะแนนระดับกลาง var num = vm.grade; num++; if (num >= vm.gradeTarget) { vm.grade = vm.gradeTarget; } อื่น ๆ { vm.grade = num; } vm.drawClrCanvas(); / 60); }, 500 } อื่น ๆ { // หลังจากเปลี่ยนหน้า ให้เริ่มต้นสถานะของหน้าข้อมูล ล้างตัวจับเวลาเพื่อหยุดภาพเคลื่อนไหว และล้างวงแหวนสี console.log (หน้าอื่น ๆ ) clearInterval(timer1); vm.aniShow = false ; vm.clearCanvas (); } } } } }, คำนวณ: {}, mount() { // เริ่มต้นข้อมูล, วาดวงกลมสีเทา vm = this; this.$refs.myCanvas; ctx = c.getContext(2d); this.drawBaseCanvas(); }, วิธีการ: { DrawBaseCanvas() { // canvas drawing/* basic value*/ var c = this.$refs.baseCanvas , //document.getElementById(myCanvas); // ดีบักเกอร์; ctx = c.getContext(2d), o = x, randius = r; /*วงกลมสีเทาเริ่มต้น*/ ctx. strokeStyle = #eee; ctx.lineWidth = 10; ctx.beginPath(); ctx.arc(o, o, randius, 0, 2 * Math.PI) ; }, clearCanvas() { // ล้างแคนวาส ctx.clearRect(0, 0, 200, 200); DrawClrCanvas() { var การไล่ระดับสี = ctx.createLinearGradient (75, 50, 5, 90); การไล่ระดับสี.addColorStop (0, #C88EFF); การไล่ระดับสี เพื่อเติม ctx.lineWidth = 10; ctx.lineCap = รอบ; ctx.shadowColor = rgba(191,142,255, 0.36); ctx.shadowBlur = 8; ctx.shadowOffsetY = 8; ctx.beginPath(); var นับ = this.grade / (100/2) + 1; x, r, Math.PI, Math.PI * นับ, เท็จ); ctx. stroke(); } };</script><style lang='scss'>// คอลัมน์chart.row { ตำแหน่ง: สัมพันธ์กัน z-index: 1; width: 0.61rem; - 0.08 - 0.38rem; text-align: center;}.data-txt { ขนาดตัวอักษร: 0.2rem; 0.2rem; margin-bottom: 0.09rem;}.progress { ความสูง: 0rem; การเปลี่ยนแปลง: ความสูง 0.5s ความง่ายในการออก;}.ani { @for $i จาก 1 ถึง 6 { &:nth-of-type( #{$i}) { .progress { ความล่าช้าในการเปลี่ยนแปลง: #{$i * 0.15}s; { // .progress { // transition-delay: .4s; // } // } // &:nth-of-type(2) { // .progress { // transition-delay: .8s; } // } // &:nth-of-type(3) { // .progress { // transition-delay: 1s; // } // } // &:nth-of-type(4) { / / .ความคืบหน้า { // การเปลี่ยนแปลงล่าช้า: 1.4s; // } // } // &: nth-of-type (5) { // .progress { // ความล่าช้าในการเปลี่ยนแปลง: 1.8s; ข้อมูล { จอแสดงผล: บล็อก; ความกว้าง: 0.12rem; ความสูง: 100%; ระยะขอบ: 0 อัตโนมัติ; พื้นหลัง: การไล่ระดับสีเชิงเส้น (0deg, #c88eff 0%, #7e5cff 100%); กล่องเงา: 0 -0.04rem 0.14rem 0 rgba (129, 93, 255, 0.4); รัศมีเส้นขอบ: 0.05rem 0.05rem 0 0;}//0 คะแนนแสดงกฎ.nodata { .pg- ข้อมูล { รัศมีเส้นขอบ: 0; พื้นหลัง: # e7e7e7; ไม่มี; }}.week { ขนาดตัวอักษร: 0.2rem; line-height: 0.2rem; margin-top: 0.08rem; : 0.32rem; height: 1.61rem;}.canvas-box { ตำแหน่ง: สัมพันธ์; 1.61rem; ความสูง: 1.61rem; .clr-canvas { ตำแหน่ง: ซ้ายสุด: 0; .canvas-data { ตำแหน่ง: สัมบูรณ์; บน: 0.56rem; ซ้าย: 0; ขวา: 0; -0.1rem; text-align: center; font-size: 0.24rem; .num { ขนาดตัวอักษร: 0.32rem;
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network